diff --git a/Dockerfile b/Dockerfile index 6074477637..07b0e0667d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -184,6 +184,17 @@ COPY --chown=$UID:$GID --from=build /app/package.json /app/package.json # copy backend files COPY --chown=$UID:$GID ./backend . +# The backend rewrites its bundled static assets (favicons, splash, manifest, +# loader.js, ...) under open_webui/static at startup. Make that directory +# writable by an arbitrary UID -- which under OpenShift's restricted SCC is +# always a member of GID 0 -- so those writes don't fail with EACCES and crash +# the boot log with "[Errno 13] Permission denied". `chmod -R g=u` mirrors the +# owner bits onto the group (the Red Hat arbitrary-UID idiom). This is applied +# unconditionally because it targets a directory the app writes on every start; +# the broader, opt-in USE_PERMISSION_HARDENING below covers the rest of /app. +RUN chgrp -R 0 /app/backend/open_webui/static && \ + chmod -R g=u /app/backend/open_webui/static + EXPOSE 8080 HEALTHCHECK CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1 diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 6dfec3c42e..b0b08c90ab 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -853,6 +853,17 @@ ONEDRIVE_SHAREPOINT_TENANT_ID = os.getenv('ONEDRIVE_SHAREPOINT_TENANT_ID', '') # RAG Content Extraction CONTENT_EXTRACTION_ENGINE = os.getenv('CONTENT_EXTRACTION_ENGINE', '').lower() +content_extraction_supported_media_mime_types = os.getenv('CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES') +CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES = ( + [ + mime_type.strip() + for mime_type in content_extraction_supported_media_mime_types.split(',') + if mime_type.strip() + ] + if content_extraction_supported_media_mime_types is not None + else None +) + DATALAB_MARKER_API_KEY = os.getenv('DATALAB_MARKER_API_KEY', '') DATALAB_MARKER_API_BASE_URL = os.getenv('DATALAB_MARKER_API_BASE_URL', '') @@ -1176,6 +1187,7 @@ WEB_SEARCH_TRUST_ENV = os.getenv('WEB_SEARCH_TRUST_ENV', 'True').lower() == 'tru OLLAMA_CLOUD_WEB_SEARCH_API_KEY = os.getenv('OLLAMA_CLOUD_API_KEY', '') SEARXNG_QUERY_URL = os.getenv('SEARXNG_QUERY_URL', '') +OPENSERP_BASE_URL = os.getenv('OPENSERP_BASE_URL', 'http://localhost:7000') SEARXNG_LANGUAGE = os.getenv('SEARXNG_LANGUAGE', 'all') @@ -1664,7 +1676,13 @@ if default_prompt_suggestions == []: DEFAULT_PROMPT_SUGGESTIONS = default_prompt_suggestions -MODEL_ORDER_LIST = [] +try: + model_order_list = json.loads(os.getenv('MODEL_ORDER_LIST', '[]')) +except Exception as e: + log.exception(f'Error loading MODEL_ORDER_LIST: {e}') + model_order_list = [] + +MODEL_ORDER_LIST = model_order_list try: default_model_metadata = json.loads(os.getenv('DEFAULT_MODEL_METADATA', '{}')) @@ -1843,6 +1861,10 @@ USER_PERMISSIONS_CHAT_ALLOW_PUBLIC_SHARING = ( os.getenv('USER_PERMISSIONS_CHAT_ALLOW_PUBLIC_SHARING', 'False').lower() == 'true' ) +USER_PERMISSIONS_CHAT_ALLOW_OPEN_SHARING = ( + os.getenv('USER_PERMISSIONS_CHAT_ALLOW_OPEN_SHARING', 'False').lower() == 'true' +) + USER_PERMISSIONS_CHAT_EXPORT = os.getenv('USER_PERMISSIONS_CHAT_EXPORT', 'True').lower() == 'true' USER_PERMISSIONS_CHAT_IMPORT = os.getenv('USER_PERMISSIONS_CHAT_IMPORT', 'True').lower() == 'true' @@ -1929,6 +1951,7 @@ DEFAULT_USER_PERMISSIONS = { 'public_notes': USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING, 'folders': USER_PERMISSIONS_FOLDERS_ALLOW_SHARING, 'public_chats': USER_PERMISSIONS_CHAT_ALLOW_PUBLIC_SHARING, + 'open_chats': USER_PERMISSIONS_CHAT_ALLOW_OPEN_SHARING, 'public_calendars': USER_PERMISSIONS_CALENDAR_ALLOW_PUBLIC_SHARING, }, 'access_grants': { @@ -1987,6 +2010,8 @@ FOLDER_MAX_FILE_COUNT = os.getenv('FOLDER_MAX_FILE_COUNT', '') ENABLE_CHANNELS = os.getenv('ENABLE_CHANNELS', 'False').lower() == 'true' +CHANNEL_MODEL_RESPONSE_MODE = os.getenv('CHANNEL_MODEL_RESPONSE_MODE', 'thread') + ENABLE_CALENDAR = os.getenv('ENABLE_CALENDAR', 'True').lower() == 'true' ENABLE_AUTOMATIONS = os.getenv('ENABLE_AUTOMATIONS', 'True').lower() == 'true' @@ -2136,6 +2161,8 @@ TASK_MODEL = os.getenv('TASK_MODEL', '') TASK_MODEL_EXTERNAL = os.getenv('TASK_MODEL_EXTERNAL', '') +CONTEXT_COMPACTION_MODEL = os.getenv('CONTEXT_COMPACTION_MODEL', '') + ENABLE_CONTEXT_COMPACTION = os.getenv('ENABLE_CONTEXT_COMPACTION', 'False').lower() == 'true' CONTEXT_COMPACTION_TOKEN_THRESHOLD = int(os.getenv('CONTEXT_COMPACTION_TOKEN_THRESHOLD', '80000')) @@ -2418,6 +2445,11 @@ if JWT_EXPIRES_IN == '-1': # OAuth config #################################### +# Master switch for OAuth/OIDC sign-in. Defaults to enabled so existing +# deployments that already have a provider configured keep working; admins can +# turn it off to disable OAuth login without clearing their provider settings. +ENABLE_OAUTH = os.getenv('ENABLE_OAUTH', 'True').lower() == 'true' + ENABLE_OAUTH_SIGNUP = os.getenv('ENABLE_OAUTH_SIGNUP', 'False').lower() == 'true' OAUTH_AUTO_REDIRECT = os.getenv('OAUTH_AUTO_REDIRECT', 'False').lower() == 'true' @@ -2582,8 +2614,7 @@ def oauth_client_kwargs(scope: str, **kwargs): client_kwargs['code_challenge_method'] = 'S256' elif OAUTH_CODE_CHALLENGE_METHOD: raise Exception( - 'Code challenge methods other than "%s" not supported. Given: "%s"' - % ('S256', OAUTH_CODE_CHALLENGE_METHOD) + 'Code challenge methods other than "%s" not supported. Given: "%s"' % ('S256', OAUTH_CODE_CHALLENGE_METHOD) ) return client_kwargs @@ -2799,6 +2830,7 @@ DEFAULT_CONFIG = { 'onedrive.sharepoint_url': ONEDRIVE_SHAREPOINT_URL, 'onedrive.sharepoint_tenant_id': ONEDRIVE_SHAREPOINT_TENANT_ID, 'rag.content_extraction_engine': CONTENT_EXTRACTION_ENGINE, + 'rag.content_extraction.supported_media_mime_types': CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES, 'rag.datalab_marker_api_key': DATALAB_MARKER_API_KEY, 'rag.datalab_marker_api_base_url': DATALAB_MARKER_API_BASE_URL, 'rag.datalab_marker_additional_config': DATALAB_MARKER_ADDITIONAL_CONFIG, @@ -2891,6 +2923,7 @@ DEFAULT_CONFIG = { 'web.search.trust_env': WEB_SEARCH_TRUST_ENV, 'web.search.ollama_cloud_api_key': OLLAMA_CLOUD_WEB_SEARCH_API_KEY, 'web.search.searxng_query_url': SEARXNG_QUERY_URL, + 'web.search.openserp_base_url': OPENSERP_BASE_URL, 'web.search.searxng_language': SEARXNG_LANGUAGE, 'web.search.yacy_query_url': YACY_QUERY_URL, 'web.search.yacy_username': YACY_USERNAME, @@ -3030,6 +3063,7 @@ DEFAULT_CONFIG = { 'folders.enable': ENABLE_FOLDERS, 'folders.max_file_count': FOLDER_MAX_FILE_COUNT, 'channels.enable': ENABLE_CHANNELS, + 'channels.model_response_mode': CHANNEL_MODEL_RESPONSE_MODE, 'calendar.enable': ENABLE_CALENDAR, 'automations.enable': ENABLE_AUTOMATIONS, 'subagents.enable': ENABLE_SUBAGENTS, @@ -3055,6 +3089,7 @@ DEFAULT_CONFIG = { 'auth.admin.email': ADMIN_EMAIL, 'task.model.default': TASK_MODEL, 'task.model.external': TASK_MODEL_EXTERNAL, + 'chat.context_compaction.model': CONTEXT_COMPACTION_MODEL, 'chat.context_compaction.enable': ENABLE_CONTEXT_COMPACTION, 'chat.context_compaction.token_threshold': CONTEXT_COMPACTION_TOKEN_THRESHOLD, 'chat.context_compaction.token_cap': CONTEXT_COMPACTION_TOKEN_CAP, @@ -3080,6 +3115,7 @@ DEFAULT_CONFIG = { 'auth.api_key.endpoint_restrictions': ENABLE_API_KEYS_ENDPOINT_RESTRICTIONS, 'auth.api_key.allowed_endpoints': API_KEYS_ALLOWED_ENDPOINTS, 'auth.jwt_expiry': JWT_EXPIRES_IN, + 'oauth.enable': ENABLE_OAUTH, 'oauth.enable_signup': ENABLE_OAUTH_SIGNUP, 'oauth.auto_redirect': OAUTH_AUTO_REDIRECT, 'oauth.refresh_token.include_scope': OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE, diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index 7449976a29..113a8ed34b 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -102,6 +102,7 @@ class JSONFormatter(logging.Formatter): LOG_FORMAT = os.getenv('LOG_FORMAT', '').lower() +LOGURU_DIAGNOSE = os.getenv('LOGURU_DIAGNOSE', 'False').lower() == 'true' GLOBAL_LOG_LEVEL = os.getenv('GLOBAL_LOG_LEVEL', '').upper() if GLOBAL_LOG_LEVEL in logging.getLevelNamesMapping(): @@ -149,6 +150,11 @@ INSTANCE_ID = os.getenv('INSTANCE_ID', str(uuid4())) ENABLE_DB_MIGRATIONS = os.getenv('ENABLE_DB_MIGRATIONS', 'True').lower() == 'true' +# Swap the JSON encoder/decoder used across the app (HTTP request bodies, JSONResponse +# bodies, upstream provider responses, socket.io payloads) from the stdlib `json` module +# to orjson. Faster, but stricter: see open_webui/utils/json_codec.py for the differences. +ENABLE_ORJSON = os.getenv('ENABLE_ORJSON', 'False').lower() == 'true' + # Function to parse each section def parse_section(section): @@ -389,6 +395,12 @@ try: except ValueError: REDIS_SOCKET_CONNECT_TIMEOUT = None +REDIS_SOCKET_TIMEOUT = os.getenv('REDIS_SOCKET_TIMEOUT', '') +try: + REDIS_SOCKET_TIMEOUT = float(REDIS_SOCKET_TIMEOUT) +except ValueError: + REDIS_SOCKET_TIMEOUT = None + # Whether to enable TCP SO_KEEPALIVE on Redis client sockets. Opt-in: # defaults to off so behavior is unchanged for existing deployments. When # enabled, the kernel sends TCP keepalive probes on idle connections so @@ -565,12 +577,28 @@ try: except (ValueError, TypeError): AIOHTTP_CLIENT_TIMEOUT = 300 +# Optional between-chunks idle cap for streaming aiohttp requests. +AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT = os.getenv('AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT', '') +if AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT == '': + AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT = None +else: + try: + AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT = int(AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT) + except (ValueError, TypeError): + AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT = None + +if AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT is not None and AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT <= 0: + AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT = None + # SSL verification for general outbound requests (OpenAI, OAuth, etc.). # Accepts "True", "False", or a path to a CA bundle file. # When "True", falls back to AIOHTTP_CLIENT_SSL_CERT_FILE if set. AIOHTTP_CLIENT_SESSION_SSL = _parse_ssl_env(os.getenv('AIOHTTP_CLIENT_SESSION_SSL', 'True')) +SEARXNG_CLIENT_CERT_FILE = os.getenv('SEARXNG_CLIENT_CERT_FILE', '').strip() +SEARXNG_CLIENT_KEY_FILE = os.getenv('SEARXNG_CLIENT_KEY_FILE', '').strip() + # When False (default), outbound HTTP requests do not follow 3xx redirects. AIOHTTP_CLIENT_ALLOW_REDIRECTS = os.getenv('AIOHTTP_CLIENT_ALLOW_REDIRECTS', 'False').lower() == 'true' @@ -797,6 +825,13 @@ OAUTH_MAX_SESSIONS_PER_USER = int(os.getenv('OAUTH_MAX_SESSIONS_PER_USER', '10') # Token Exchange Configuration # Allows external apps to exchange OAuth tokens for OpenWebUI tokens ENABLE_OAUTH_TOKEN_EXCHANGE = os.getenv('ENABLE_OAUTH_TOKEN_EXCHANGE', 'False').lower() == 'true' +_oauth_token_exchange_rate_limit = (os.getenv('OAUTH_TOKEN_EXCHANGE_RATE_LIMIT') or '').strip() +OAUTH_TOKEN_EXCHANGE_RATE_LIMIT = ( + int(_oauth_token_exchange_rate_limit) + if _oauth_token_exchange_rate_limit and _oauth_token_exchange_rate_limit.lower() != 'none' + else None +) +OAUTH_TOKEN_EXCHANGE_RATE_LIMIT_WINDOW = int(os.getenv('OAUTH_TOKEN_EXCHANGE_RATE_LIMIT_WINDOW', str(60 * 3))) # OAuth client IDs whose tokens the exchange endpoint will accept. A provider's # userinfo endpoint confirms a token is valid, never which client it was minted @@ -1052,6 +1087,28 @@ SENTENCE_TRANSFORMERS_CROSS_ENCODER_SIGMOID_ACTIVATION_FUNCTION = ( os.getenv('SENTENCE_TRANSFORMERS_CROSS_ENCODER_SIGMOID_ACTIVATION_FUNCTION', 'True').lower() == 'true' ) +#################################### +# KNOWLEDGE TOOLS +#################################### + + +def _int_env(name: str, default: int) -> int: + try: + return max(int(os.getenv(name) or default), 1) + except (ValueError, TypeError): + return default + + +# Total output of a single kb_exec call, whatever the command. +KB_EXEC_MAX_OUTPUT_CHARS = _int_env('KB_EXEC_MAX_OUTPUT_CHARS', 30_000) +# Files a single kb_exec grep may scan before it asks for a narrower scope. +KB_EXEC_MAX_GREP_FILES = _int_env('KB_EXEC_MAX_GREP_FILES', 200) +# Matching lines returned by kb_exec grep and grep_knowledge_files. +KNOWLEDGE_GREP_MAX_MATCHES = _int_env('KNOWLEDGE_GREP_MAX_MATCHES', 50) +# Characters returned by view_file / view_knowledge_file. +VIEW_FILE_MAX_CHARS = _int_env('VIEW_FILE_MAX_CHARS', 100_000) +VIEW_FILE_DEFAULT_MAX_CHARS = _int_env('VIEW_FILE_DEFAULT_MAX_CHARS', 10_000) + #################################### # TOOLS/FUNCTIONS PIP OPTIONS #################################### diff --git a/backend/open_webui/events.py b/backend/open_webui/events.py index b627c69a18..999a1c826c 100644 --- a/backend/open_webui/events.py +++ b/backend/open_webui/events.py @@ -483,6 +483,16 @@ class EventDefinitions(BaseModel): FUNCTION_DISABLED: EventDefinition = EventDefinition( name='function.disabled', description='A function was disabled.', message='Function disabled' ) + FUNCTION_ENABLE_STARTED: EventDefinition = EventDefinition( + name='function.enable_started', + description='A function is about to be enabled.', + message='Function enable started', + ) + FUNCTION_DISABLE_STARTED: EventDefinition = EventDefinition( + name='function.disable_started', + description='A function is about to be disabled.', + message='Function disable started', + ) FUNCTION_VALVES_UPDATED: EventDefinition = EventDefinition( name='function.valves_updated', description='Function valves were updated.', message='Function valves updated' ) @@ -1067,7 +1077,9 @@ class NotificationEventSink: schedule_notification_dispatch(app, event) -async def dispatch_event_functions(app: Any, event: Event, request: Any | None = None) -> None: +async def dispatch_event_functions( + app: Any, event: Event, request: Any | None = None, extra_function_ids: list[str] | None = None +) -> None: if not ENABLE_PLUGINS: return @@ -1079,6 +1091,12 @@ async def dispatch_event_functions(app: Any, event: Event, request: Any | None = try: event_functions = await Functions.get_functions_by_type('event', active_only=True) + if extra_function_ids: + extra_functions = await Functions.get_functions_by_ids(extra_function_ids) + existing_ids = {function.id for function in event_functions} + event_functions.extend( + function for function in extra_functions if function.type == 'event' and function.id not in existing_ids + ) except Exception: log.exception('Event functions could not be loaded for %s', event.event) return diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 15412572b0..55613ac83d 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -220,10 +220,16 @@ from open_webui.utils.chat import ( from open_webui.utils.chat import ( generate_chat_completion as chat_completion_handler, ) +from open_webui.utils.chat_id import ( + get_temporary_chat_session_id, + is_saved_chat_id, + is_temporary_chat_id, +) from open_webui.utils.chat_variables import ( normalize_chat_variables, ) from open_webui.utils.embeddings import generate_embeddings +from open_webui.utils.json_response import apply_orjson_http_json from open_webui.utils.logger import start_logger from open_webui.utils.middleware import ( background_tasks_handler, @@ -231,6 +237,7 @@ from open_webui.utils.middleware import ( process_chat_payload, process_chat_response, ) +from open_webui.utils.model_ids import strip_provider_model_prefix from open_webui.utils.models import ( check_model_access, get_all_base_models, @@ -252,7 +259,7 @@ from open_webui.utils.oauth import ( from open_webui.utils.plugin import install_tool_and_function_dependencies from open_webui.utils.redis import get_redis_client from open_webui.utils.security_headers import SecurityHeadersMiddleware -from open_webui.utils.session_pool import get_session +from open_webui.utils.session_pool import cleanup_response, get_session, stream_wrapper from open_webui.utils.tools import set_terminal_servers, set_tool_servers if SAFE_MODE: @@ -264,12 +271,13 @@ log = logging.getLogger(__name__) async def emit_chat_list_event(metadata: dict, chat_id: str): - if not chat_id or chat_id.startswith(('channel:', 'local:')): + if not is_saved_chat_id(chat_id): return event_emitter = await get_event_emitter(metadata, update_db=False) if event_emitter: - await event_emitter({'type': 'chat:list', 'data': {'chat_id': chat_id}}) + folder_id = metadata.get('folder_id') or await Chats.get_chat_folder_id(chat_id, metadata.get('user_id')) + await event_emitter({'type': 'chat:list', 'data': {'chat_id': chat_id, 'folder_id': folder_id}}) class SPAStaticFiles(StaticFiles): @@ -449,6 +457,10 @@ async def lifespan(app: FastAPI): await publish_event(app, EVENTS.SYSTEM_SHUTDOWN_COMPLETED, source='system') +# Opt-in (ENABLE_ORJSON): orjson for request-body parsing and JSONResponse bodies; +# response_model routes keep FastAPI's Pydantic fast path either way. +apply_orjson_http_json() + app = FastAPI( title='Open WebUI', docs_url='/docs' if ENV == 'dev' else None, @@ -830,7 +842,9 @@ async def get_models(request: Request, refresh: bool = False, user=Depends(get_v all_models = await get_all_models(request, refresh=refresh, user=user) # Filter out filter pipelines - models = [model for model in all_models if not ('pipeline' in model and model['pipeline'].get('type', None) == 'filter')] + models = [ + model for model in all_models if not ('pipeline' in model and model['pipeline'].get('type', None) == 'filter') + ] # Chat requests resolve models by ID from request.app.state.MODELS, where # duplicate IDs collapse to the last model. Return the same effective list. @@ -883,12 +897,6 @@ class ModelUnloadForm(BaseModel): model: str -def strip_provider_model_prefix(model_id: str, prefix_id: str | None) -> str: - if prefix_id and model_id.startswith(f'{prefix_id}.'): - return model_id[len(f'{prefix_id}.') :] - return model_id - - @app.post('/api/models/unload') async def unload_model(request: Request, form_data: ModelUnloadForm, user=Depends(get_admin_user)): """ @@ -1030,6 +1038,17 @@ async def embeddings(request: Request, form_data: dict, user=Depends(get_verifie return await generate_embeddings(request, form_data, user) +async def _set_direct_model(request: Request, model_item: dict, user) -> None: + model_meta = (model_item.get('info') or {}).get('meta') or {} + knowledge_items = model_meta.get('knowledge') + if knowledge_items: + from open_webui.utils.access_control.files import get_accessible_folder_files + + model_meta['knowledge'] = await get_accessible_folder_files(knowledge_items, user) + request.state.direct = True + request.state.model = model_item + + @app.post('/api/chat/completions') @app.post('/api/v1/chat/completions') # Experimental: Compatibility with OpenAI API async def chat_completion( @@ -1057,14 +1076,12 @@ async def chat_completion( # Check if user has access to the model if not BYPASS_MODEL_ACCESS_CONTROL and (user.role != 'admin' or not BYPASS_ADMIN_ACCESS_CONTROL): try: - await check_model_access(user, model) + await check_model_access(user, model, model_info=model_info) except Exception as e: raise e else: model = model_item - - request.state.direct = True - request.state.model = model + await _set_direct_model(request, model, user) # Model params: global defaults as base, per-model overrides win default_model_params = await Config.get('models.default_params', {}) or {} @@ -1141,7 +1158,7 @@ async def chat_completion( chat_id = form_data.get('chat_id') or '' chat_variables = form_data.pop('chat_variables', None) if chat_variables is None: - existing_chat = await Chats.get_chat_by_id(chat_id) if chat_id else None + existing_chat = await Chats.get_chat_by_id(chat_id) if is_saved_chat_id(chat_id) else None chat_variables = existing_chat.variables if existing_chat else {} chat_variables = normalize_chat_variables(chat_variables) @@ -1240,9 +1257,7 @@ async def chat_completion( detail=ERROR_MESSAGES.DEFAULT(), ) - if not chat_id.startswith('local:') and not chat_id.startswith( - 'channel:' - ): # temporary/channel chats are not stored + if is_saved_chat_id(chat_id): if is_new_chat: # Build the full history upfront with ALL assistant placeholders user_message = metadata.get('user_message') or {} @@ -1259,7 +1274,7 @@ async def chat_completion( target_model_id = entry['model_id'] assistant_message_id = entry['message_id'] if assistant_message_id: - history_messages[assistant_message_id] = { + assistant_message = { 'id': assistant_message_id, 'parentId': user_message_id, 'childrenIds': [], @@ -1269,6 +1284,11 @@ async def chat_completion( 'model': target_model_id, 'timestamp': int(time.time()), } + # Preserve the side-by-side column index so duplicate + # models don't collapse into one another on reload. + if entry.get('modelIdx') is not None: + assistant_message['modelIdx'] = entry['modelIdx'] + history_messages[assistant_message_id] = assistant_message await Chats.insert_new_chat( chat_id, @@ -1395,7 +1415,7 @@ async def chat_completion( updated['files'] = chat_files if selected_chat_models: updated['models'] = selected_chat_models - await Chats.update_chat_by_id(chat_id, updated) + await Chats.update_chat_by_id(chat_id, updated, touch=False) await Chats.update_chat_variables_by_id(chat_id, chat_variables) @@ -1424,7 +1444,7 @@ async def chat_completion( try: from open_webui.utils.timers import cancel_timers_for_chat - await cancel_timers_for_chat(chat_id, 'chat.user_message') + await cancel_timers_for_chat(chat_id, 'chat.user_message', user.id) except Exception: log.exception('Failed to cancel chat.user_message timers for chat %s', chat_id) @@ -1481,19 +1501,24 @@ async def chat_completion( target_model_id = entry['model_id'] assistant_message_id = entry['message_id'] if assistant_message_id: + assistant_message = { + 'id': assistant_message_id, + 'parentId': user_message_id, + 'childrenIds': [], + 'role': 'assistant', + 'content': '', + 'done': False, + 'model': target_model_id, + 'timestamp': int(time.time()), + } + # Preserve the side-by-side column index so duplicate + # models don't collapse into one another on reload. + if entry.get('modelIdx') is not None: + assistant_message['modelIdx'] = entry['modelIdx'] await Chats.upsert_message_to_chat_by_id_and_message_id( chat_id, assistant_message_id, - { - 'id': assistant_message_id, - 'parentId': user_message_id, - 'childrenIds': [], - 'role': 'assistant', - 'content': '', - 'done': False, - 'model': target_model_id, - 'timestamp': int(time.time()), - }, + assistant_message, ) await publish_event( request, @@ -1562,9 +1587,7 @@ async def chat_completion( if metadata.get('chat_id') and metadata.get('message_id'): # Update the chat message with the error try: - if not metadata.get('chat_id', '').startswith('local:') and not metadata.get( - 'chat_id', '' - ).startswith('channel:'): + if is_saved_chat_id(metadata.get('chat_id')): await Chats.upsert_message_to_chat_by_id_and_message_id( metadata['chat_id'], metadata['message_id'], @@ -1632,7 +1655,17 @@ async def chat_completion( event_emitter = await get_event_emitter(metadata, update_db=False) if event_emitter: try: - await asyncio.shield(event_emitter({'type': 'chat:active', 'data': {'active': False}})) + folder_id = metadata.get('folder_id') or await Chats.get_chat_folder_id( + chat_id, user.id + ) + await asyncio.shield( + event_emitter( + { + 'type': 'chat:active', + 'data': {'active': False, 'folder_id': folder_id}, + } + ) + ) except asyncio.CancelledError: pass except Exception: @@ -1683,6 +1716,7 @@ async def chat_completion( per_model_metadata = { **metadata, 'message_id': assistant_message_id, + 'task_id': str(uuid4()), } # Per-model form_data: own model @@ -1718,8 +1752,8 @@ async def chat_completion( request.app.state.redis, process, id=chat_id, + task_id=per_model_metadata['task_id'], ) - per_model_metadata['task_id'] = task_id task_ids.append(task_id) if is_internal: @@ -1737,7 +1771,8 @@ async def chat_completion( update_db=False, ) if event_emitter: - await event_emitter({'type': 'chat:active', 'data': {'active': True}}) + folder_id = metadata.get('folder_id') or await Chats.get_chat_folder_id(chat_id, user.id) + await event_emitter({'type': 'chat:active', 'data': {'active': True, 'folder_id': folder_id}}) return { 'status': True, @@ -1769,6 +1804,7 @@ app.state.CHAT_COMPLETION_HANDLER = chat_completion from open_webui.utils.anthropic import ( convert_anthropic_to_openai_payload, convert_openai_to_anthropic_response, + is_anthropic_messages_passthrough, openai_stream_to_anthropic_stream, ) @@ -1783,6 +1819,65 @@ async def count_message_tokens( return {'input_tokens': await openai.count_anthropic_tokens(request, form_data, user)} +async def passthrough_anthropic_messages(request: Request, form_data: dict, user) -> Response | dict: + requested_model, payload, url, key, headers, cookies = await openai.get_anthropic_token_count_target( + request, form_data, user + ) + request_url = f'{url.rstrip("/")}/messages' + response = None + streaming = False + + try: + session = await get_session() + response = await session.request( + method='POST', + url=request_url, + data=json.dumps(payload), + headers=headers, + cookies=cookies, + ssl=AIOHTTP_CLIENT_SESSION_SSL, + timeout=aiohttp.ClientTimeout(total=openai.AIOHTTP_CLIENT_TIMEOUT), + ) + + if 'text/event-stream' in response.headers.get('Content-Type', ''): + streaming = True + return StreamingResponse( + stream_wrapper(response), + status_code=response.status, + headers=openai._clean_proxy_headers(response.headers), + ) + + try: + response_data = await response.json() + except Exception: + response_data = await response.text() + + if response.status >= 400: + await openai.publish_model_provider_request_failed( + request, + actor=user, + provider='openai-compatible', + base_url=url, + api_key=key, + status=response.status, + requested_model=requested_model, + upstream_error=response_data, + ) + if isinstance(response_data, (dict, list)): + return JSONResponse(status_code=response.status, content=response_data) + return Response(status_code=response.status, content=response_data) + + return response_data + except HTTPException: + raise + except Exception: + log.exception('Failed to passthrough Anthropic Messages request for model %s', requested_model) + raise HTTPException(status_code=502, detail=ERROR_MESSAGES.SERVER_CONNECTION_ERROR) + finally: + if not streaming: + await cleanup_response(response) + + @app.post('/api/message') @app.post('/api/v1/messages') # Anthropic Messages API compatible endpoint async def generate_messages( @@ -1823,11 +1918,20 @@ async def generate_messages( models = request.app.state.OPENAI_MODELS model = models.get(model_id) if model: - _, _, api_config = await openai.get_openai_connection(model['urlIdx']) + url, _, api_config = await openai.get_openai_connection(model['urlIdx']) + if is_anthropic_messages_passthrough(url, api_config): + return await passthrough_anthropic_messages(request, form_data, user) passthrough_params = api_config.get('passthrough_params') or [] # Convert Anthropic payload to OpenAI format openai_payload = convert_anthropic_to_openai_payload(form_data, passthrough_params) + model_meta = model_info.meta.model_dump() if model_info and model_info.meta else {} + if (model_meta.get('capabilities') or {}).get('usage') is True: + if openai_payload.get('stream'): + stream_options = openai_payload.get('stream_options') + if not isinstance(stream_options, dict): + stream_options = {} + openai_payload['stream_options'] = {**stream_options, 'include_usage': True} # Route through the existing chat_completion handler response = await chat_completion(request, openai_payload, user) @@ -1836,9 +1940,7 @@ async def generate_messages( if isinstance(response, StreamingResponse): # Streaming response: wrap the generator to convert SSE format return StreamingResponse( - openai_stream_to_anthropic_stream( - response.body_iterator, model=requested_model, input_tokens=input_tokens or 0 - ), + openai_stream_to_anthropic_stream(response.body_iterator, model=requested_model, input_tokens=input_tokens), media_type='text/event-stream', headers={ 'Cache-Control': 'no-cache', @@ -1852,16 +1954,36 @@ async def generate_messages( return response +async def verify_chat_ownership(chat_id: str | None, user) -> None: + """Temporary chats are per-socket and unsaved, so they have no owner to check.""" + if not chat_id or is_temporary_chat_id(chat_id): + return + + # Channel messages need the membership and write-access gate that only /api/chat/completions has. + if chat_id.startswith('channel:'): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Channel chats are not supported on this endpoint', + ) + + if user.role != 'admin' and not await Chats.is_chat_owner(chat_id, user.id): + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.DEFAULT(), + ) + + @app.post('/api/chat/completed') async def chat_completed(request: Request, form_data: dict, user=Depends(get_verified_user)): """Deprecated: outlet filters now run inline during chat completion. Kept for backward compatibility with external integrations.""" + await verify_chat_ownership(form_data.get('chat_id'), user) + try: model_item = form_data.pop('model_item', {}) if model_item.get('direct', False): - request.state.direct = True - request.state.model = model_item + await _set_direct_model(request, model_item, user) return await chat_completed_handler(request, form_data, user) except Exception as e: @@ -1873,12 +1995,13 @@ async def chat_completed(request: Request, form_data: dict, user=Depends(get_ver @app.post('/api/chat/actions/{action_id}') async def chat_action(request: Request, action_id: str, form_data: dict, user=Depends(get_verified_user)): + await verify_chat_ownership(form_data.get('chat_id'), user) + try: model_item = form_data.pop('model_item', {}) if model_item.get('direct', False): - request.state.direct = True - request.state.model = model_item + await _set_direct_model(request, model_item, user) return await chat_action_handler(request, action_id, form_data, user) except Exception as e: @@ -1904,8 +2027,8 @@ async def list_tasks_endpoint(request: Request, user=Depends(get_admin_user)): @app.get('/api/tasks/chat/{chat_id:path}') async def list_tasks_by_chat_id_endpoint(request: Request, chat_id: str, user=Depends(get_verified_user)): - if chat_id.startswith('local:') or chat_id.startswith('channel:'): - socket_id = chat_id[len('local:') :] + socket_id = get_temporary_chat_session_id(chat_id) + if socket_id: owner_id = get_user_id_from_session_pool(socket_id) if owner_id != user.id and user.role != 'admin': return {'task_ids': []} @@ -1922,8 +2045,8 @@ async def list_tasks_by_chat_id_endpoint(request: Request, chat_id: str, user=De @app.post('/api/tasks/chat/{chat_id:path}/stop') async def stop_tasks_by_chat_id_endpoint(request: Request, chat_id: str, user=Depends(get_verified_user)): - if chat_id.startswith('local:') or chat_id.startswith('channel:'): - socket_id = chat_id[len('local:') :] + socket_id = get_temporary_chat_session_id(chat_id) + if socket_id: owner_id = get_user_id_from_session_pool(socket_id) if owner_id != user.id and user.role != 'admin': raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND) @@ -1975,6 +2098,7 @@ async def get_app_config(request: Request): license_metadata = getattr(app.state, 'LICENSE_METADATA', None) user_count = await Users.get_num_users() if license_metadata else None config = await Config.get_many( + 'oauth.enable', 'oauth.auto_redirect', 'ldap.enable', 'ui.enable_signup', @@ -2029,7 +2153,13 @@ async def get_app_config(request: Request): 'version': VERSION, 'default_locale': str(DEFAULT_LOCALE), 'oauth': { - 'providers': {name: config.get('name', name) for name, config in OAUTH_PROVIDERS.items()}, + # Hide providers (and thus the login buttons / auto-redirect) when OAuth + # is disabled, without clearing the admin's provider configuration. + 'providers': ( + {name: provider.get('name', name) for name, provider in OAUTH_PROVIDERS.items()} + if config.get('oauth.enable', True) + else {} + ), 'auto_redirect': config.get('oauth.auto_redirect'), }, 'features': { diff --git a/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py b/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py new file mode 100644 index 0000000000..1298abd41d --- /dev/null +++ b/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py @@ -0,0 +1,54 @@ +"""add automation folder id + +Revision ID: 959eaac8f909 +Revises: 55f1302ac17c +Create Date: 2026-07-26 19:19:31.345756 + +""" + +from collections.abc import Sequence + +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision: str = '959eaac8f909' +down_revision: str | None = '55f1302ac17c' +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + if context.is_offline_mode(): + op.add_column('automation', sa.Column('folder_id', sa.Text(), nullable=True)) + op.create_index('ix_automation_user_folder', 'automation', ['user_id', 'folder_id']) + return + + conn = op.get_bind() + inspector = sa.inspect(conn) + columns = {col['name'] for col in inspector.get_columns('automation')} + indexes = {index['name'] for index in inspector.get_indexes('automation')} + + if 'folder_id' not in columns: + op.add_column('automation', sa.Column('folder_id', sa.Text(), nullable=True)) + + if 'ix_automation_user_folder' not in indexes: + op.create_index('ix_automation_user_folder', 'automation', ['user_id', 'folder_id']) + + +def downgrade() -> None: + if context.is_offline_mode(): + op.drop_index('ix_automation_user_folder', table_name='automation') + op.drop_column('automation', 'folder_id') + return + + conn = op.get_bind() + inspector = sa.inspect(conn) + columns = {col['name'] for col in inspector.get_columns('automation')} + indexes = {index['name'] for index in inspector.get_indexes('automation')} + + if 'ix_automation_user_folder' in indexes: + op.drop_index('ix_automation_user_folder', table_name='automation') + + if 'folder_id' in columns: + op.drop_column('automation', 'folder_id') diff --git a/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py b/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py index 73d3687c1f..d8e94ca60b 100644 --- a/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py +++ b/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py @@ -5,6 +5,7 @@ Revises: c49178636c78 Create Date: 2026-07-24 01:21:46.457057 """ + from typing import Sequence, Union import sqlalchemy as sa diff --git a/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py b/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py index 7823f3867c..c4d4aaf355 100644 --- a/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py +++ b/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py @@ -5,6 +5,7 @@ Revises: 9a1b2c3d4e5f Create Date: 2026-07-23 23:33:45.497453 """ + from typing import Sequence, Union import sqlalchemy as sa diff --git a/backend/open_webui/models/access_grants.py b/backend/open_webui/models/access_grants.py index f944ff8655..7cca23546c 100644 --- a/backend/open_webui/models/access_grants.py +++ b/backend/open_webui/models/access_grants.py @@ -11,6 +11,11 @@ from sqlalchemy.ext.asyncio import AsyncSession log = logging.getLogger(__name__) +PRINCIPAL_TYPE_ANYONE = 'anyone' +PRINCIPAL_TYPE_GROUP = 'group' +PRINCIPAL_TYPE_USER = 'user' +WILDCARD_PRINCIPAL_ID = '*' + #################### # AccessGrant DB Schema @@ -23,7 +28,7 @@ class AccessGrant(Base): id = Column(Text, primary_key=True) resource_type = Column(Text, nullable=False) # "knowledge", "model", "prompt", "tool", "note", "channel", "file" resource_id = Column(Text, nullable=False) - principal_type = Column(Text, nullable=False) # "user" or "group" + principal_type = Column(Text, nullable=False) # "user", "group", or "anyone" principal_id = Column(Text, nullable=False) # user_id, group_id, or "*" (wildcard for public) permission = Column(Text, nullable=False) # "read" or "write" created_at = Column(BigInteger, nullable=False) @@ -163,12 +168,14 @@ def normalize_access_grants(access_grants: Optional[list]) -> list[dict]: principal_id = grant.get('principal_id') permission = grant.get('permission') - if principal_type not in ('user', 'group'): + if principal_type not in (PRINCIPAL_TYPE_USER, PRINCIPAL_TYPE_GROUP, PRINCIPAL_TYPE_ANYONE): continue if permission not in ('read', 'write'): continue if not isinstance(principal_id, str) or not principal_id: continue + if principal_type == PRINCIPAL_TYPE_ANYONE and (principal_id != WILDCARD_PRINCIPAL_ID or permission != 'read'): + continue key = (principal_type, principal_id, permission) deduped[key] = { @@ -186,7 +193,11 @@ def has_public_read_access_grant(access_grants: Optional[list]) -> bool: Returns True when a direct grant list includes wildcard public-read. """ for grant in normalize_access_grants(access_grants): - if grant['principal_type'] == 'user' and grant['principal_id'] == '*' and grant['permission'] == 'read': + if ( + grant['principal_type'] == PRINCIPAL_TYPE_USER + and grant['principal_id'] == WILDCARD_PRINCIPAL_ID + and grant['permission'] == 'read' + ): return True return False @@ -196,7 +207,25 @@ def has_public_write_access_grant(access_grants: Optional[list]) -> bool: Returns True when a direct grant list includes wildcard public-write. """ for grant in normalize_access_grants(access_grants): - if grant['principal_type'] == 'user' and grant['principal_id'] == '*' and grant['permission'] == 'write': + if ( + grant['principal_type'] == PRINCIPAL_TYPE_USER + and grant['principal_id'] == WILDCARD_PRINCIPAL_ID + and grant['permission'] == 'write' + ): + return True + return False + + +def has_anyone_read_access_grant(access_grants: Optional[list]) -> bool: + """ + Returns True when a direct grant list includes no-auth anyone-read. + """ + for grant in normalize_access_grants(access_grants): + if ( + grant['principal_type'] == PRINCIPAL_TYPE_ANYONE + and grant['principal_id'] == WILDCARD_PRINCIPAL_ID + and grant['permission'] == 'read' + ): return True return False @@ -206,7 +235,7 @@ def has_user_access_grant(access_grants: Optional[list]) -> bool: Returns True when a direct grant list includes any non-wildcard user grant. """ for grant in normalize_access_grants(access_grants): - if grant['principal_type'] == 'user' and grant['principal_id'] != '*': + if grant['principal_type'] == PRINCIPAL_TYPE_USER and grant['principal_id'] != WILDCARD_PRINCIPAL_ID: return True return False @@ -223,12 +252,27 @@ def strip_user_access_grants(access_grants: Optional[list]) -> list: for grant in access_grants if not ( (grant.get('principal_type') if isinstance(grant, dict) else getattr(grant, 'principal_type', None)) - == 'user' - and (grant.get('principal_id') if isinstance(grant, dict) else getattr(grant, 'principal_id', None)) != '*' + == PRINCIPAL_TYPE_USER + and (grant.get('principal_id') if isinstance(grant, dict) else getattr(grant, 'principal_id', None)) + != WILDCARD_PRINCIPAL_ID ) ] +def strip_anyone_access_grants(access_grants: Optional[list]) -> list: + """ + Remove no-auth anyone grants from the list. + """ + if not access_grants: + return [] + return [ + grant + for grant in access_grants + if (grant.get('principal_type') if isinstance(grant, dict) else getattr(grant, 'principal_type', None)) + != PRINCIPAL_TYPE_ANYONE + ] + + def grants_to_access_control(grants: list) -> Optional[dict]: """ Convert a list of grant objects (AccessGrantModel or AccessGrantResponse) @@ -493,6 +537,28 @@ class AccessGrantsTable: result_dict[g.resource_id].append(AccessGrantModel.model_validate(g)) return result_dict + async def has_anyone_access( + self, + resource_type: str, + resource_id: str, + permission: str = 'read', + db: Optional[AsyncSession] = None, + ) -> bool: + """Check for a no-auth anyone:* grant. Callers must opt in explicitly.""" + async with get_async_db_context(db) as db: + result = await db.execute( + select(AccessGrant) + .filter( + AccessGrant.resource_type == resource_type, + AccessGrant.resource_id == resource_id, + AccessGrant.principal_type == PRINCIPAL_TYPE_ANYONE, + AccessGrant.principal_id == WILDCARD_PRINCIPAL_ID, + AccessGrant.permission == permission, + ) + .limit(1) + ) + return result.scalars().first() is not None + async def has_access( self, user_id: str, diff --git a/backend/open_webui/models/automations.py b/backend/open_webui/models/automations.py index fbd74ccf5e..c0a7416cc6 100644 --- a/backend/open_webui/models/automations.py +++ b/backend/open_webui/models/automations.py @@ -21,6 +21,7 @@ class Automation(Base): id = Column(Text, primary_key=True) user_id = Column(Text, nullable=False) + folder_id = Column(Text, nullable=True) name = Column(Text, nullable=False) data = Column(JSON, nullable=False) # {prompt, model_id, rrule} meta = Column(JSON, nullable=True) @@ -31,7 +32,10 @@ class Automation(Base): created_at = Column(BigInteger, nullable=False) updated_at = Column(BigInteger, nullable=False) - __table_args__ = (Index('ix_automation_next_run', 'next_run_at'),) + __table_args__ = ( + Index('ix_automation_next_run', 'next_run_at'), + Index('ix_automation_user_folder', 'user_id', 'folder_id'), + ) class AutomationRun(Base): @@ -72,6 +76,7 @@ class AutomationModel(BaseModel): id: str user_id: str + folder_id: Optional[str] = None name: str data: dict meta: Optional[dict] = None @@ -96,6 +101,7 @@ class AutomationRunModel(BaseModel): class AutomationForm(BaseModel): name: str + folder_id: Optional[str] = None data: AutomationData meta: Optional[dict] = None is_active: Optional[bool] = True @@ -129,6 +135,7 @@ class AutomationTable: row = Automation( id=str(uuid4()), user_id=user_id, + folder_id=form.folder_id, name=form.name, data=form.data.model_dump(), meta=form.meta, @@ -164,6 +171,7 @@ class AutomationTable: user_id: str, query: Optional[str] = None, status: Optional[str] = None, + folder_id: Optional[str] = None, skip: int = 0, limit: int = 30, db: Optional[AsyncSession] = None, @@ -171,6 +179,9 @@ class AutomationTable: async with get_async_db_context(db) as db: stmt = select(Automation).filter_by(user_id=user_id) + if folder_id is not None: + stmt = stmt.filter(Automation.folder_id == (folder_id or None)) + if query: search = f'%{query}%' # Search in name and prompt inside JSON data @@ -216,6 +227,7 @@ class AutomationTable: if not row: return None row.name = form.name + row.folder_id = form.folder_id row.data = form.data.model_dump() row.meta = form.meta if form.is_active is not None: @@ -225,6 +237,23 @@ class AutomationTable: await db.commit() return AutomationModel.model_validate(row) + async def clear_folder_ids( + self, + user_id: str, + folder_ids: list[str], + db: Optional[AsyncSession] = None, + ) -> int: + if not folder_ids: + return 0 + async with get_async_db_context(db) as db: + result = await db.execute( + update(Automation) + .where(Automation.user_id == user_id, Automation.folder_id.in_(folder_ids)) + .values(folder_id=None, updated_at=int(time.time_ns())) + ) + await db.commit() + return result.rowcount or 0 + async def toggle( self, id: str, diff --git a/backend/open_webui/models/calendar.py b/backend/open_webui/models/calendar.py index b9be370f31..efdfd291ba 100644 --- a/backend/open_webui/models/calendar.py +++ b/backend/open_webui/models/calendar.py @@ -241,11 +241,11 @@ class CalendarTable: access_grants: Optional[list[AccessGrantModel]] = None, db: Optional[AsyncSession] = None, ) -> CalendarModel: - cal_data = CalendarModel.model_validate(cal).model_dump(exclude={'access_grants'}) - cal_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(cal_data['id'], db=db) + calendar_model = CalendarModel.model_validate(cal) + calendar_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(calendar_model.id, db=db) ) - return CalendarModel.model_validate(cal_data) + return calendar_model async def get_or_create_defaults(self, user_id: str, db: Optional[AsyncSession] = None) -> list[CalendarModel]: """Return user's calendars, creating 'Personal' default if none exist.""" @@ -777,9 +777,7 @@ class CalendarEventAttendeeTable: existing_status = { row.user_id: row.status for row in ( - await db.execute( - select(CalendarEventAttendee).filter(CalendarEventAttendee.event_id == event_id) - ) + await db.execute(select(CalendarEventAttendee).filter(CalendarEventAttendee.event_id == event_id)) ).scalars() } diff --git a/backend/open_webui/models/channels.py b/backend/open_webui/models/channels.py index 5028cdf2c8..95cc58cd32 100644 --- a/backend/open_webui/models/channels.py +++ b/backend/open_webui/models/channels.py @@ -266,11 +266,11 @@ class ChannelTable: access_grants: Optional[list[AccessGrantModel]] = None, db: Optional[AsyncSession] = None, ) -> ChannelModel: - channel_data = ChannelModel.model_validate(channel).model_dump(exclude={'access_grants'}) - channel_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(channel_data['id'], db=db) + channel_model = ChannelModel.model_validate(channel) + channel_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(channel_model.id, db=db) ) - return ChannelModel.model_validate(channel_data) + return channel_model async def _collect_unique_user_ids( self, diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py index b2e252f588..279b037fdf 100644 --- a/backend/open_webui/models/chats.py +++ b/backend/open_webui/models/chats.py @@ -27,6 +27,7 @@ from sqlalchemy import ( UniqueConstraint, and_, delete, + exists, func, or_, select, @@ -35,13 +36,37 @@ from sqlalchemy import ( ) from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm.attributes import flag_modified -from sqlalchemy.sql import exists +from sqlalchemy.sql import case, exists from sqlalchemy.sql.expression import bindparam log = logging.getLogger(__name__) ACTIVE_CHAT_GAP_SECONDS = 30 * 60 +def chat_list_order(sort_by: str = 'updated_at', sort_dir: str = 'desc', user_id: str | None = None): + if sort_by != 'unread_updated_at': + sort_column = Chat.title if sort_by == 'title' else Chat.updated_at + order_clause = sort_column.asc() if sort_dir == 'asc' else sort_column.desc() + return order_clause, Chat.id + + unfinished_assistant = ( + select(ChatMessage.id) + .where(ChatMessage.chat_id == Chat.id) + .where(ChatMessage.role == 'assistant') + .where(ChatMessage.done.is_(False)) + .exists() + ) + conditions = [Chat.updated_at > func.coalesce(Chat.last_read_at, 0), ~unfinished_assistant] + if user_id is not None: + conditions.append(Chat.user_id == user_id) + + unread = case( + (and_(*conditions), 1), + else_=0, + ) + return unread.desc(), Chat.updated_at.desc(), Chat.id + + class Chat(Base): # database table mapping for chat entity __tablename__ = 'chat' @@ -538,7 +563,7 @@ class ChatTable: await session.commit() # Dual-write messages to chat_message table - for form_data, chat_obj in zip(chat_import_forms, chats): + for form_data, imported_chat in zip(chat_import_forms, chats): history = form_data.chat.get('history') if isinstance(form_data.chat.get('history'), dict) else {} messages = history.get('messages') if isinstance(history.get('messages'), dict) else {} if not messages and isinstance(form_data.chat.get('messages'), list): @@ -552,12 +577,14 @@ class ChatTable: try: await ChatMessages.upsert_message( message_id=message_id, - chat_id=chat_obj.id, + chat_id=imported_chat.id, user_id=user_id, data=message, ) except Exception as e: - log.warning(f'Failed to write imported message {message_id} for chat {chat_obj.id}: {e}') + log.warning( + f'Failed to write imported message {message_id} for chat {imported_chat.id}: {e}' + ) return [ChatModel.model_validate(chat) for chat in chats] @@ -613,17 +640,75 @@ class ChatTable: except Exception: return None - async def update_chat_last_read_at_by_id(self, id: str, user_id: str, db: AsyncSession | None = None) -> bool: + async def update_chat_last_read_at_by_id( + self, id: str, user_id: str, db: AsyncSession | None = None + ) -> tuple[int, bool] | None: try: async with get_async_db_context(db) as session: chat = await session.get(Chat, id) if chat and chat.user_id == user_id: - chat.last_read_at = int(time.time()) + last_read_at = int(time.time()) + was_unread = chat.last_read_at is None or chat.updated_at > chat.last_read_at + chat.last_read_at = last_read_at await session.commit() - return True - return False + return last_read_at, was_unread + return None except Exception: - return False + return None + + async def mark_chat_unread_by_id( + self, id: str, user_id: str, db: AsyncSession | None = None + ) -> ChatTitleIdResponse | None: + try: + async with get_async_db_context(db) as session: + chat = await session.get(Chat, id) + if chat and chat.user_id == user_id: + chat.last_read_at = 0 + await session.commit() + return ChatTitleIdResponse( + id=chat.id, + title=chat.title, + updated_at=chat.updated_at, + created_at=chat.created_at, + last_read_at=chat.last_read_at, + ) + return None + except Exception: + return None + + async def mark_chats_read_by_folder_ids( + self, user_id: str, folder_ids: list[str], db: AsyncSession | None = None + ) -> int: + if not folder_ids: + return 0 + + async with get_async_db_context(db) as session: + result = await session.execute( + update(Chat) + .where( + Chat.user_id == user_id, + Chat.folder_id.in_(folder_ids), + Chat.archived == False, + Chat.meta['internal'].as_boolean().is_not(True), + ) + .values(last_read_at=Chat.updated_at) + ) + await session.commit() + return result.rowcount or 0 + + async def mark_chats_read_by_user_id(self, user_id: str, db: AsyncSession | None = None) -> int: + async with get_async_db_context(db) as session: + result = await session.execute( + update(Chat) + .where( + Chat.user_id == user_id, + Chat.archived == False, + Chat.meta['internal'].as_boolean().is_not(True), + ) + .values(last_read_at=Chat.updated_at) + ) + await session.commit() + return result.rowcount or 0 async def update_chat_title_by_id(self, id: str, title: str) -> ChatModel | None: try: @@ -639,30 +724,32 @@ class ChatTable: except Exception: return None - async def update_chat_tags_by_id(self, id: str, tags: list[str], user) -> ChatModel | None: + async def update_chat_tags_by_id(self, id: str, tags: list[str], user) -> None: + """Replace a chat's tags. Runs after every completion with tag + generation enabled, so only the meta column is read and written, + never the chat blob.""" async with get_async_db_context() as session: - chat = await session.get(Chat, id) - if chat is None: + row = (await session.execute(select(Chat.meta).filter_by(id=id))).one_or_none() + if row is None: return None - old_tags = chat.meta.get('tags', []) + meta = row[0] or {} + old_tags = meta.get('tags', []) new_tags = [t for t in tags if t.replace(' ', '_').lower() != 'none'] new_tag_ids = [t.replace(' ', '_').lower() for t in new_tags] # Single meta update - chat.meta = {**chat.meta, 'tags': new_tag_ids} + await session.execute(update(Chat).filter_by(id=id).values(meta={**meta, 'tags': new_tag_ids})) await session.commit() # Batch-create any missing tag rows await Tags.ensure_tags_exist(new_tags, user.id, db=session) - # Clean up orphaned old tags in one query + # Clean up orphaned old tags removed = set(old_tags) - set(new_tag_ids) if removed: await self.delete_orphan_tags_for_user(list(removed), user.id, db=session) - return ChatModel.model_validate(chat) - async def get_chat_title_by_id(self, id: str) -> str | None: async with get_async_db_context() as session: result = await session.execute(select(Chat.title).filter_by(id=id)) @@ -745,6 +832,54 @@ class ChatTable: history['currentId'] = current_id if current_id in messages else None return deleted_ids + @staticmethod + def upsert_message_to_history(history: dict, message_id: str, message: dict) -> dict: + messages = history.setdefault('messages', {}) + + if message_id in messages: + messages[message_id] = { + **messages[message_id], + **message, + } + else: + message_parent_id = message.get('parentId') + parent_id = message_parent_id + if parent_id is None: + for existing_id, existing_message in messages.items(): + if message_id in existing_message.get('childrenIds', []): + parent_id = existing_id + break + + parent = messages.get(parent_id) if parent_id else None + output = message.get('output') or [] + output_role = next( + (item.get('role') for item in output if isinstance(item, dict) and item.get('role')), + None, + ) + role = message.get('role') or output_role + if not role: + parent_role = parent.get('role') if parent else None + if parent_role == 'user': + role = 'assistant' + elif parent_role == 'assistant': + role = 'user' + else: + role = 'assistant' + + messages[message_id] = { + **message, + 'id': message.get('id') or message_id, + 'parentId': message_parent_id if message_parent_id is not None else parent_id, + 'childrenIds': ( + message.get('childrenIds') if isinstance(message.get('childrenIds'), list) else [] + ), + 'role': role, + 'timestamp': message.get('timestamp') or int(time.time()), + } + + history['currentId'] = message_id + return messages[message_id] + async def backfill_messages_by_chat_id(self, chat_id: str, user_id: str, messages: dict[str, dict]) -> None: """Write messages to the ``chat_message`` table so future lookups use the fast path. Errors are logged but never raised. @@ -836,10 +971,6 @@ class ChatTable: async def upsert_message_to_chat_by_id_and_message_id( self, id: str, message_id: str, message: dict, *, touch: bool = True ) -> ChatModel | None: - chat = await self.get_chat_by_id(id) - if chat is None: - return None - if not message.get('content'): output_text = get_output_text(message.get('output')) if output_text: @@ -849,105 +980,121 @@ class ChatTable: if isinstance(message.get('content'), str): message['content'] = sanitize_text_for_db(message['content']) - user_id = chat.user_id - chat = chat.chat - history = chat.get('history', {}) - messages = history.setdefault('messages', {}) - - if message_id in messages: - messages[message_id] = { - **messages[message_id], - **message, - } - else: - message_parent_id = message.get('parentId') - parent_id = message_parent_id - if parent_id is None: - for existing_id, existing_message in messages.items(): - if message_id in existing_message.get('childrenIds', []): - parent_id = existing_id - break - - parent = messages.get(parent_id) if parent_id else None - output = message.get('output') or [] - output_role = next( - (item.get('role') for item in output if isinstance(item, dict) and item.get('role')), - None, - ) - role = message.get('role') or output_role - if not role: - parent_role = parent.get('role') if parent else None - if parent_role == 'user': - role = 'assistant' - elif parent_role == 'assistant': - role = 'user' - else: - role = 'assistant' - - messages[message_id] = { - **message, - 'id': message.get('id') or message_id, - 'parentId': message_parent_id if message_parent_id is not None else parent_id, - 'childrenIds': message.get('childrenIds') if isinstance(message.get('childrenIds'), list) else [], - 'role': role, - 'timestamp': message.get('timestamp') or int(time.time()), - } - - history['currentId'] = message_id - - chat['history'] = history - - # Dual-write to chat_message table try: - await ChatMessages.upsert_message( - message_id=message_id, - chat_id=id, - user_id=user_id, - data=messages[message_id], - ) - except Exception as e: - log.warning(f'Failed to write to chat_message table: {e}') + async with get_async_db_context() as session: + chat_item = await session.get(Chat, id) + if chat_item is None: + return None - return await self.update_chat_by_id(id, chat, touch=touch) + self._sanitize_chat_row(chat_item) + chat = chat_item.chat or {} + self._repair_chat_current_id(chat) - async def delete_message_from_chat_by_id_and_message_id(self, id: str, message_id: str) -> ChatModel | None: - chat_model = await self.get_chat_by_id(id) - if chat_model is None: + history = chat.get('history', {}) + saved_message = self.upsert_message_to_history(history, message_id, message) + chat['history'] = history + clean_chat = self._clean_null_bytes(chat) + chat_item.chat = clean_chat + chat_item.title = self._clean_null_bytes(clean_chat['title']) if 'title' in clean_chat else 'New Chat' + chat_item.current_message_id = self.get_current_message_id(clean_chat) + flag_modified(chat_item, 'chat') + + if touch: + chat_item.updated_at = int(time.time()) + + await session.commit() + updated_chat = ChatModel.model_validate(chat_item) + user_id = chat_item.user_id + + # Dual-write to chat_message table + try: + await ChatMessages.upsert_message( + message_id=message_id, + chat_id=id, + user_id=user_id, + data=saved_message, + ) + except Exception as e: + log.warning(f'Failed to write to chat_message table: {e}') + + return updated_chat + except Exception: return None - chat = chat_model.chat - history = chat.get('history', {}) - deleted_ids = self.delete_message_from_history(history, message_id) - if not deleted_ids: - return chat_model + async def delete_message_from_chat_by_id_and_message_id(self, id: str, message_id: str) -> ChatModel | None: + try: + async with get_async_db_context() as session: + chat_item = await session.get(Chat, id) + if chat_item is None: + return None - messages = history.get('messages') or {} - chat['history'] = history - updated_chat = await self.update_chat_by_id(id, chat) + self._sanitize_chat_row(chat_item) + chat = chat_item.chat or {} + self._repair_chat_current_id(chat) - await self.backfill_messages_by_chat_id(id, chat_model.user_id, messages) - await ChatMessages.delete_message_ids_by_chat_id(id, deleted_ids) + history = chat.get('history', {}) + deleted_ids = self.delete_message_from_history(history, message_id) + if not deleted_ids: + clean_chat = self._clean_null_bytes(chat) + chat_item.chat = clean_chat + chat_item.title = ( + self._clean_null_bytes(clean_chat['title']) if 'title' in clean_chat else 'New Chat' + ) + chat_item.current_message_id = self.get_current_message_id(clean_chat) + flag_modified(chat_item, 'chat') + await session.commit() + return ChatModel.model_validate(chat_item) - return updated_chat + messages = history.get('messages') or {} + chat['history'] = history + clean_chat = self._clean_null_bytes(chat) + chat_item.chat = clean_chat + chat_item.title = self._clean_null_bytes(clean_chat['title']) if 'title' in clean_chat else 'New Chat' + chat_item.current_message_id = self.get_current_message_id(clean_chat) + flag_modified(chat_item, 'chat') + chat_item.updated_at = int(time.time()) + await session.commit() + updated_chat = ChatModel.model_validate(chat_item) + user_id = chat_item.user_id + + await self.backfill_messages_by_chat_id(id, user_id, messages) + await ChatMessages.delete_message_ids_by_chat_id(id, deleted_ids) + + return updated_chat + except Exception: + return None async def add_message_status_to_chat_by_id_and_message_id( self, id: str, message_id: str, status: dict ) -> ChatModel | None: - chat = await self.get_chat_by_id(id) - if chat is None: + try: + async with get_async_db_context() as session: + chat_item = await session.get(Chat, id) + if chat_item is None: + return None + + self._sanitize_chat_row(chat_item) + chat = chat_item.chat or {} + self._repair_chat_current_id(chat) + history = chat.get('history', {}) + + if message_id in history.get('messages', {}): + status_history = history['messages'][message_id].get('statusHistory', []) + status_history.append(status) + history['messages'][message_id]['statusHistory'] = status_history + + chat['history'] = history + clean_chat = self._clean_null_bytes(chat) + chat_item.chat = clean_chat + chat_item.title = self._clean_null_bytes(clean_chat['title']) if 'title' in clean_chat else 'New Chat' + chat_item.current_message_id = self.get_current_message_id(clean_chat) + flag_modified(chat_item, 'chat') + await session.commit() + + return ChatModel.model_validate(chat_item) + except Exception: return None - chat = chat.chat - history = chat.get('history', {}) - - if message_id in history.get('messages', {}): - status_history = history['messages'][message_id].get('statusHistory', []) - status_history.append(status) - history['messages'][message_id]['statusHistory'] = status_history - - chat['history'] = history - return await self.update_chat_by_id(id, chat, touch=False) - async def add_message_files_by_id_and_message_id(self, id: str, message_id: str, files: list[dict]) -> list[dict]: async with get_async_db_context() as session: chat = await self.get_chat_by_id(id, db=session) @@ -1210,6 +1357,8 @@ class ChatTable: include_archived: bool = False, include_folders: bool = False, include_pinned: bool = False, + sort_by: str = 'updated_at', + sort_dir: str = 'desc', skip: int | None = None, limit: int | None = None, db: AsyncSession | None = None, @@ -1229,7 +1378,7 @@ class ChatTable: if not include_archived: stmt = stmt.filter_by(archived=False) - stmt = stmt.order_by(Chat.updated_at.desc(), Chat.id) + stmt = stmt.order_by(*chat_list_order(sort_by, sort_dir)) if skip: stmt = stmt.offset(skip) @@ -1435,6 +1584,37 @@ class ChatTable: except Exception: return None + async def count_unread_by_folder_ids( + self, + user_id: str, + folder_ids: list[str], + db: AsyncSession | None = None, + ) -> dict[str, int]: + if not folder_ids: + return {} + + unfinished_assistant = ( + select(ChatMessage.id) + .where(ChatMessage.chat_id == Chat.id) + .where(ChatMessage.role == 'assistant') + .where(ChatMessage.done.is_(False)) + .exists() + ) + + async with get_async_db_context(db) as session: + result = await session.execute( + select(Chat.folder_id, func.count(Chat.id)) + .where( + Chat.user_id == user_id, + Chat.folder_id.in_(folder_ids), + Chat.archived == False, + Chat.updated_at > func.coalesce(Chat.last_read_at, 0), + ~unfinished_assistant, + ) + .group_by(Chat.folder_id) + ) + return {folder_id: count for folder_id, count in result.all() if folder_id} + async def get_chats(self, skip: int = 0, limit: int = 50, db: AsyncSession | None = None) -> list[ChatModel]: async with get_async_db_context(db) as session: stmt = select(Chat).where(Chat.meta['internal'].as_boolean().is_not(True)) @@ -1769,6 +1949,8 @@ class ChatTable: user_id: str, skip: int = 0, limit: int = 60, + sort_by: str = 'updated_at', + sort_dir: str = 'desc', db: AsyncSession | None = None, ) -> list[ChatTitleIdResponse]: async with get_async_db_context(db) as session: @@ -1778,8 +1960,8 @@ class ChatTable: .filter(or_(Chat.pinned == False, Chat.pinned == None)) .filter_by(archived=False) .where(Chat.meta['internal'].as_boolean().is_not(True)) - .order_by(Chat.updated_at.desc(), Chat.id) ) + stmt = stmt.order_by(*chat_list_order(sort_by, sort_dir)) if skip: stmt = stmt.offset(skip) @@ -1808,20 +1990,19 @@ class ChatTable: limit: int = 60, sort_by: str = 'updated_at', sort_dir: str = 'desc', + unread_for_user_id: str | None = None, db: AsyncSession | None = None, ) -> list[dict]: """Get chats in a folder across ALL users. Returns dicts with user_id.""" async with get_async_db_context(db) as session: - sort_column = Chat.title if sort_by == 'title' else Chat.updated_at - order_clause = sort_column.asc() if sort_dir == 'asc' else sort_column.desc() stmt = ( select(Chat.id, Chat.title, Chat.user_id, Chat.updated_at, Chat.created_at, Chat.last_read_at) .filter_by(folder_id=folder_id) .filter(or_(Chat.pinned == False, Chat.pinned == None)) .filter_by(archived=False) .where(Chat.meta['internal'].as_boolean().is_not(True)) - .order_by(order_clause, Chat.id) ) + stmt = stmt.order_by(*chat_list_order(sort_by, sort_dir, unread_for_user_id)) if skip: stmt = stmt.offset(skip) @@ -1885,6 +2066,11 @@ class ChatTable: chat.updated_at = int(time.time()) chat.last_read_at = int(time.time()) chat.pinned = False + if folder_id is not None: + # Folder listings only show unarchived chats, so moving an archived + # chat into a folder would otherwise have no visible effect: the chat + # stays in the archived list and never appears in the folder. + chat.archived = False await session.commit() return ChatModel.model_validate(chat) except Exception: @@ -1953,45 +2139,66 @@ class ChatTable: async def add_chat_tag_by_id_and_user_id_and_tag_name( self, id: str, user_id: str, tag_name: str, db: AsyncSession | None = None - ) -> ChatModel | None: + ) -> None: + """Add one tag to a chat's meta. Meta-column-only, never the blob.""" tag_id = tag_name.replace(' ', '_').lower() await Tags.ensure_tags_exist([tag_name], user_id, db=db) try: async with get_async_db_context(db) as session: - chat = await session.get(Chat, id) - if tag_id not in chat.meta.get('tags', []): - chat.meta = { - **chat.meta, - 'tags': list(set(chat.meta.get('tags', []) + [tag_id])), - } - await session.commit() - return ChatModel.model_validate(chat) + row = (await session.execute(select(Chat.meta).filter_by(id=id))).one_or_none() + if row is None: + return None + + meta = row[0] or {} + if tag_id not in meta.get('tags', []): + await session.execute( + update(Chat) + .filter_by(id=id) + .values(meta={**meta, 'tags': list(set(meta.get('tags', []) + [tag_id]))}) + ) + await session.commit() except Exception: return None async def count_chats_by_tag_name_and_user_id( self, tag_name: str, user_id: str, db: AsyncSession | None = None ) -> int: - async with get_async_db_context(db) as session: - stmt = select(func.count(Chat.id)).filter_by(user_id=user_id, archived=False) - stmt = stmt.where(Chat.meta['internal'].as_boolean().is_not(True)) - tag_id = tag_name.replace(' ', '_').lower() + tag_id = tag_name.replace(' ', '_').lower() + counts = await self.count_chats_by_tag_ids_and_user_id([tag_id], user_id, db=db) + return counts.get(tag_id, 0) + async def count_chats_by_tag_ids_and_user_id( + self, tag_ids: list[str], user_id: str, db: AsyncSession | None = None + ) -> dict[str, int]: + """Per-tag chat counts in one round trip (one scalar subquery per tag).""" + if not tag_ids: + return {} + async with get_async_db_context(db) as session: bind = await session.connection() dialect_name = bind.dialect.name - if dialect_name == 'sqlite': - stmt = stmt.filter( - text("EXISTS (SELECT 1 FROM json_each(Chat.meta, '$.tags') WHERE json_each.value = :tag_id)") - ).params(tag_id=tag_id) - elif dialect_name == 'postgresql': - stmt = stmt.filter( - text("EXISTS (SELECT 1 FROM json_array_elements_text(Chat.meta->'tags') elem WHERE elem = :tag_id)") - ).params(tag_id=tag_id) - else: - raise NotImplementedError(f'Unsupported dialect: {dialect_name}') - result = await session.execute(stmt) - return result.scalar() + columns = [] + for index, tag_id in enumerate(tag_ids): + tag_id = tag_id.replace(' ', '_').lower() + stmt = select(func.count(Chat.id)).filter_by(user_id=user_id, archived=False) + stmt = stmt.where(Chat.meta['internal'].as_boolean().is_not(True)) + param = f'tag_id_{index}' + if dialect_name == 'sqlite': + stmt = stmt.filter( + text(f"EXISTS (SELECT 1 FROM json_each(Chat.meta, '$.tags') WHERE json_each.value = :{param})") + ).params(**{param: tag_id}) + elif dialect_name == 'postgresql': + stmt = stmt.filter( + text( + f"EXISTS (SELECT 1 FROM json_array_elements_text(Chat.meta->'tags') elem WHERE elem = :{param})" + ) + ).params(**{param: tag_id}) + else: + raise NotImplementedError(f'Unsupported dialect: {dialect_name}') + columns.append(stmt.scalar_subquery().label(f'count_{index}')) + + row = (await session.execute(select(*columns))).one() + return dict(zip(tag_ids, row)) async def delete_orphan_tags_for_user( self, @@ -2011,11 +2218,8 @@ class ChatTable: if not tag_ids: return async with get_async_db_context(db) as session: - orphans = [] - for tag_id in tag_ids: - count = await self.count_chats_by_tag_name_and_user_id(tag_id, user_id, db=session) - if count <= threshold: - orphans.append(tag_id) + counts = await self.count_chats_by_tag_ids_and_user_id(tag_ids, user_id, db=session) + orphans = [tag_id for tag_id in tag_ids if counts.get(tag_id, 0) <= threshold] await Tags.delete_tags_by_ids_and_user_id(orphans, user_id, db=session) async def count_chats_by_folder_id_and_user_id( diff --git a/backend/open_webui/models/config.py b/backend/open_webui/models/config.py index 00fcfc2e00..6081214b4c 100644 --- a/backend/open_webui/models/config.py +++ b/backend/open_webui/models/config.py @@ -46,6 +46,7 @@ API_CONFIG_FIELDS = ( 'auth_type', 'headers', 'azure', + 'api_type', 'api_version', 'extra_params', 'passthrough_params', diff --git a/backend/open_webui/models/folders.py b/backend/open_webui/models/folders.py index a06a5c51f8..11d5dd5427 100644 --- a/backend/open_webui/models/folders.py +++ b/backend/open_webui/models/folders.py @@ -58,6 +58,7 @@ class FolderNameIdResponse(BaseModel): meta: Optional[FolderMetadataResponse] = None parent_id: Optional[str] = None is_expanded: bool = False + unread_count: int = 0 created_at: int updated_at: int diff --git a/backend/open_webui/models/knowledge.py b/backend/open_webui/models/knowledge.py index 3163a24f49..52a78c46c1 100644 --- a/backend/open_webui/models/knowledge.py +++ b/backend/open_webui/models/knowledge.py @@ -36,6 +36,9 @@ from sqlalchemy.orm import defer log = logging.getLogger(__name__) +# Columns the knowledge base list may be ordered by; anything else falls back to the default. +KNOWLEDGE_SORTABLE_FIELDS = {'name', 'created_at', 'updated_at'} + #################### # Knowledge DB Schema # Let what was gathered here outlast the one who gathered it, @@ -192,11 +195,11 @@ class KnowledgeTable: access_grants: Optional[list[AccessGrantModel]] = None, db: Optional[AsyncSession] = None, ) -> KnowledgeModel: - knowledge_data = KnowledgeModel.model_validate(knowledge).model_dump(exclude={'access_grants'}) - knowledge_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(knowledge_data['id'], db=db) + knowledge_model = KnowledgeModel.model_validate(knowledge) + knowledge_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(knowledge_model.id, db=db) ) - return KnowledgeModel.model_validate(knowledge_data) + return knowledge_model async def insert_new_knowledge( self, user_id: str, form_data: KnowledgeForm, db: Optional[AsyncSession] = None @@ -309,7 +312,17 @@ class KnowledgeTable: permission='read', ) - stmt = stmt.order_by(Knowledge.updated_at.desc(), Knowledge.id.asc()) + order_by = (filter or {}).get('order_by') + direction = (filter or {}).get('direction') + + if order_by in KNOWLEDGE_SORTABLE_FIELDS: + column = getattr(Knowledge, order_by) + if (direction or 'desc').lower() == 'asc': + stmt = stmt.order_by(column.asc(), Knowledge.id.asc()) + else: + stmt = stmt.order_by(column.desc(), Knowledge.id.asc()) + else: + stmt = stmt.order_by(Knowledge.updated_at.desc(), Knowledge.id.asc()) count_result = await db.execute(select(func.count()).select_from(stmt.subquery())) total = count_result.scalar() diff --git a/backend/open_webui/models/models.py b/backend/open_webui/models/models.py index 5f44d59405..839e47c6d3 100755 --- a/backend/open_webui/models/models.py +++ b/backend/open_webui/models/models.py @@ -199,11 +199,11 @@ class ModelsTable: if db is not None: await db.commit() - model_data = ModelModel.model_validate(model).model_dump(exclude={'access_grants'}) - model_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(model_data['id'], db=db) + model_model = ModelModel.model_validate(model) + model_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(model_model.id, db=db) ) - return ModelModel.model_validate(model_data) + return model_model async def insert_new_model( self, form_data: ModelForm, user_id: str, db: AsyncSession | None = None @@ -555,12 +555,12 @@ class ModelsTable: try: async with get_async_db_context(db) as db: result = await db.execute(select(Model).filter_by(id=id)) - model_obj = result.scalars().first() - if not model_obj: + model = result.scalars().first() + if not model: return None - model_obj.updated_at = int(time.time()) + model.updated_at = int(time.time()) await db.commit() - return await self._to_model_model(model_obj, db=db) + return await self._to_model_model(model, db=db) except Exception as e: log.exception(f'Failed to update the model updated_at by id {id}: {e}') return None diff --git a/backend/open_webui/models/notes.py b/backend/open_webui/models/notes.py index 55e19e7aaf..8d8eb2414f 100644 --- a/backend/open_webui/models/notes.py +++ b/backend/open_webui/models/notes.py @@ -106,11 +106,12 @@ class NoteTable: db: Optional[AsyncSession] = None, ) -> NoteModel: # We exclude access_grants to inject them - note_data = NoteModel.model_validate(note).model_dump(exclude={'access_grants'}) - note_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(note_data['id'], db=db) + note_model = NoteModel.model_validate(note) + note_model.data = note_model.data or {} + note_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(note_model.id, db=db) ) - return NoteModel.model_validate(note_data) + return note_model def _has_permission(self, db, query, filter: dict, permission: str = 'read'): return AccessGrants.has_permission_filter( @@ -308,9 +309,9 @@ class NoteTable: if 'title' in form_data: note.title = form_data['title'] if 'data' in form_data: - note.data = {**note.data, **form_data['data']} + note.data = {**(note.data or {}), **(form_data['data'] or {})} if 'meta' in form_data: - note.meta = {**note.meta, **form_data['meta']} + note.meta = {**(note.meta or {}), **(form_data['meta'] or {})} if not db.is_modified(note) and 'access_grants' not in form_data: return await self._to_note_model(note, db=db) diff --git a/backend/open_webui/models/prompts.py b/backend/open_webui/models/prompts.py index 61ce0fc218..f4f4187f17 100644 --- a/backend/open_webui/models/prompts.py +++ b/backend/open_webui/models/prompts.py @@ -103,11 +103,11 @@ class PromptsTable: access_grants: list[AccessGrantModel | None] = None, db: AsyncSession | None = None, ) -> PromptModel: - prompt_data = PromptModel.model_validate(prompt).model_dump(exclude={'access_grants'}) - prompt_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(prompt_data['id'], db=db) + prompt_model = PromptModel.model_validate(prompt) + prompt_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(prompt_model.id, db=db) ) - return PromptModel.model_validate(prompt_data) + return prompt_model async def insert_new_prompt( self, user_id: str, form_data: PromptForm, db: AsyncSession | None = None diff --git a/backend/open_webui/models/skills.py b/backend/open_webui/models/skills.py index c3c007cdd9..b4a64fd02d 100644 --- a/backend/open_webui/models/skills.py +++ b/backend/open_webui/models/skills.py @@ -113,11 +113,11 @@ class SkillsTable: access_grants: Optional[list[AccessGrantModel]] = None, db: Optional[AsyncSession] = None, ) -> SkillModel: - skill_data = SkillModel.model_validate(skill).model_dump(exclude={'access_grants'}) - skill_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(skill_data['id'], db=db) + skill_model = SkillModel.model_validate(skill) + skill_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(skill_model.id, db=db) ) - return SkillModel.model_validate(skill_data) + return skill_model async def insert_new_skill( self, diff --git a/backend/open_webui/models/tools.py b/backend/open_webui/models/tools.py index 86568288e0..cbc21854ea 100644 --- a/backend/open_webui/models/tools.py +++ b/backend/open_webui/models/tools.py @@ -106,11 +106,11 @@ class ToolsTable: access_grants: list[AccessGrantModel | None] = None, db: AsyncSession | None = None, ) -> ToolModel: - tool_data = ToolModel.model_validate(tool).model_dump(exclude={'access_grants'}) - tool_data['access_grants'] = ( - access_grants if access_grants is not None else await self._get_access_grants(tool_data['id'], db=db) + tool_model = ToolModel.model_validate(tool) + tool_model.access_grants = ( + access_grants if access_grants is not None else await self._get_access_grants(tool_model.id, db=db) ) - return ToolModel.model_validate(tool_data) + return tool_model async def insert_new_tool( self, diff --git a/backend/open_webui/retrieval/external.py b/backend/open_webui/retrieval/external.py index dcfc575fc8..1f0c06d8a7 100644 --- a/backend/open_webui/retrieval/external.py +++ b/backend/open_webui/retrieval/external.py @@ -4,6 +4,7 @@ import re import time from typing import Any, Optional +from open_webui.config import RAG_EMBEDDING_QUERY_PREFIX from open_webui.models.config import Config from open_webui.models.knowledge import KnowledgeModel @@ -103,7 +104,7 @@ async def _retrieve_qdrant(connection, auth_config, knowledge, query, count, emb source_config = _source_config(knowledge) vector_field = source_config.get('vector_field') or None - vector = await embedding_function(query) + vector = await embedding_function(query, prefix=RAG_EMBEDDING_QUERY_PREFIX) def _search(): client = QdrantClient( @@ -152,7 +153,7 @@ async def _retrieve_milvus(connection, auth_config, knowledge, query, count, emb content_field = source_config.get('content_field') or 'data.text' metadata_field = source_config.get('metadata_field') or 'metadata' - vector = await embedding_function(query) + vector = await embedding_function(query, prefix=RAG_EMBEDDING_QUERY_PREFIX) def _search(): client_kwargs = { @@ -229,7 +230,7 @@ async def _retrieve_pgvector(connection, auth_config, knowledge, query, count, e metadata_field = source_config.get('metadata_field') or 'vmetadata' document_id_field = source_config.get('document_id_field') or 'id' - vector = await embedding_function(query) + vector = await embedding_function(query, prefix=RAG_EMBEDDING_QUERY_PREFIX) def _search(): from psycopg import sql diff --git a/backend/open_webui/retrieval/loaders/external_document.py b/backend/open_webui/retrieval/loaders/external_document.py index 2dd70dbd4b..c199fabcef 100644 --- a/backend/open_webui/retrieval/loaders/external_document.py +++ b/backend/open_webui/retrieval/loaders/external_document.py @@ -6,7 +6,7 @@ from urllib.parse import quote import requests from langchain_core.document_loaders import BaseLoader from langchain_core.documents import Document -from open_webui.utils.headers import get_custom_headers, include_user_info_headers +from open_webui.utils.headers import include_user_info_headers, parse_custom_headers log = logging.getLogger(__name__) @@ -19,6 +19,7 @@ class ExternalDocumentLoader(BaseLoader): api_key: str, mime_type=None, user=None, + user_groups=None, headers=None, metadata=None, **kwargs, @@ -30,6 +31,7 @@ class ExternalDocumentLoader(BaseLoader): self.mime_type = mime_type self.user = user + self.user_groups = user_groups self.headers = headers self.metadata = metadata @@ -49,7 +51,7 @@ class ExternalDocumentLoader(BaseLoader): except Exception: pass - headers.update(get_custom_headers(self.headers, self.user, self.metadata)) + headers.update(parse_custom_headers(self.headers, self.user, self.metadata, user_groups=self.user_groups)) if self.user is not None: headers = include_user_info_headers(headers, self.user) diff --git a/backend/open_webui/retrieval/loaders/main.py b/backend/open_webui/retrieval/loaders/main.py index 54f71d7234..4972f3ddab 100644 --- a/backend/open_webui/retrieval/loaders/main.py +++ b/backend/open_webui/retrieval/loaders/main.py @@ -11,7 +11,6 @@ from langchain_community.document_loaders import ( BSHTMLLoader, CSVLoader, Docx2txtLoader, - OutlookMessageLoader, PyPDFLoader, TextLoader, YoutubeLoader, @@ -27,7 +26,8 @@ from open_webui.retrieval.loaders.datalab_marker import DatalabMarkerLoader from open_webui.retrieval.loaders.external_document import ExternalDocumentLoader from open_webui.retrieval.loaders.mineru import MinerULoader from open_webui.retrieval.loaders.mistral import MistralLoader -from open_webui.retrieval.loaders.paddleocr_vl import PaddleOCRVLLoader +from open_webui.retrieval.loaders.paddleocr_vl import PADDLEOCR_VL_SUPPORTED_EXTENSIONS, PaddleOCRVLLoader +from open_webui.utils.headers import get_user_groups_for_custom_headers logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) log = logging.getLogger(__name__) @@ -206,6 +206,9 @@ class DoclingLoader: data={ 'image_export_mode': 'placeholder', 'md_page_break_placeholder': page_break_marker, + # Keep Docling params as user-provided form values. Encoding nested + # values here would make Open WebUI responsible for Docling's API + # quirks and could break when Docling changes its form contract. **self.params, }, headers=headers, @@ -246,6 +249,7 @@ class Loader: def __init__(self, engine: str = '', **kwargs): self.engine = engine self.user = kwargs.get('user', None) + self.user_groups = kwargs.get('user_groups', None) self.metadata = kwargs.get('metadata', {}) self.kwargs = kwargs @@ -264,6 +268,13 @@ class Loader: loop for the entire parse — minutes for large PDFs. This offloads the work to a worker thread so the loop stays responsive. """ + # Group lookup is async-only, so it must happen before `load` + # is offloaded to a thread without a running event loop. + if self.engine == 'external' and self.user_groups is None: + self.user_groups = await get_user_groups_for_custom_headers( + self.kwargs.get('EXTERNAL_DOCUMENT_LOADER_HEADERS'), self.user + ) + return await asyncio.to_thread(self.load, filename, file_content_type, file_path) def _is_text_file(self, file_ext: str, file_content_type: str) -> bool: @@ -303,13 +314,20 @@ class Loader: try: raw.decode('utf-8') return 'utf-8' - except UnicodeDecodeError: - pass + except UnicodeDecodeError as e: + first_non_utf8 = e.start # Use chardet as a hint, not as ground truth import chardet - detected = chardet.detect(raw) + # chardet is pure Python (~1.3s/MB), so sample around the first bad byte + window = 256 * 1024 + sample_start = max(0, first_non_utf8 - window // 2) + sample = raw[sample_start : sample_start + window] + detected = chardet.detect(sample) + # A stray byte can sit far from the real payload, leaving the sample with nothing to read + if len(sample.translate(None, delete=bytes(range(128)))) < 64 and len(sample) < len(raw): + detected = chardet.detect(raw) detected_enc = (detected.get('encoding') or '').lower().replace('-', '').replace('_', '') # Map chardet's detected encoding to the correct superset codec. @@ -422,6 +440,7 @@ class Loader: api_key=self.kwargs.get('EXTERNAL_DOCUMENT_LOADER_API_KEY'), mime_type=file_content_type, user=self.user, + user_groups=self.user_groups, headers=self.kwargs.get('EXTERNAL_DOCUMENT_LOADER_HEADERS'), metadata={ **self.metadata, @@ -556,7 +575,12 @@ class Loader: use_base64=self.kwargs.get('MISTRAL_OCR_USE_BASE64', False), user=self.user, ) - elif self.engine == 'paddleocr_vl' and self.kwargs.get('PADDLEOCR_VL_TOKEN') != '': + elif ( + self.engine == 'paddleocr_vl' + and self.kwargs.get('PADDLEOCR_VL_BASE_URL') + and self.kwargs.get('PADDLEOCR_VL_TOKEN') + and file_ext in PADDLEOCR_VL_SUPPORTED_EXTENSIONS + ): loader = PaddleOCRVLLoader( api_url=self.kwargs.get('PADDLEOCR_VL_BASE_URL'), token=self.kwargs.get('PADDLEOCR_VL_TOKEN'), @@ -655,7 +679,18 @@ class Loader: ) loader = PptxLoader(file_path) elif file_ext == 'msg': - loader = OutlookMessageLoader(file_path) + try: + from langchain_community.document_loaders import ( + UnstructuredEmailLoader, + ) + + # unstructured parses .msg via python-oxmsg; avoids extract_msg's beautifulsoup4<4.14 conflict + loader = UnstructuredEmailLoader(file_path, process_attachments=False) + except ImportError: + raise ValueError( + "Processing .msg files requires the 'unstructured' package. " + 'Install it with: pip install unstructured' + ) elif file_ext == 'odt': try: from langchain_community.document_loaders import UnstructuredODTLoader diff --git a/backend/open_webui/retrieval/loaders/paddleocr_vl.py b/backend/open_webui/retrieval/loaders/paddleocr_vl.py index 40c185eab6..50172ddb47 100644 --- a/backend/open_webui/retrieval/loaders/paddleocr_vl.py +++ b/backend/open_webui/retrieval/loaders/paddleocr_vl.py @@ -11,6 +11,9 @@ from open_webui.env import GLOBAL_LOG_LEVEL logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) log = logging.getLogger(__name__) +PADDLEOCR_VL_IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'bmp', 'tiff', 'webp'] +PADDLEOCR_VL_SUPPORTED_EXTENSIONS = ['pdf'] + PADDLEOCR_VL_IMAGE_EXTENSIONS + class PaddleOCRVLLoader: """Loader that uses PaddleOCR-vl API to extract text from PDF/images.""" @@ -46,8 +49,7 @@ class PaddleOCRVLLoader: # Detect fileType based on file extension ext = self.file_path.lower().split('.')[-1] - image_extensions = ['png', 'jpg', 'jpeg', 'bmp', 'tiff', 'webp'] - file_type = 1 if ext in image_extensions else 0 + file_type = 1 if ext in PADDLEOCR_VL_IMAGE_EXTENSIONS else 0 payload = { 'file': file_data, diff --git a/backend/open_webui/retrieval/utils.py b/backend/open_webui/retrieval/utils.py index f816efb8fc..1119fdbce9 100644 --- a/backend/open_webui/retrieval/utils.py +++ b/backend/open_webui/retrieval/utils.py @@ -632,7 +632,7 @@ def merge_and_sort_query_results(query_results: list[dict], k: int) -> dict: for distance, document, metadata in zip(distances, documents, metadatas): if isinstance(document, str): - doc_hash = hashlib.sha256(document.encode()).hexdigest() # Compute a hash for uniqueness + doc_hash = (metadata or {}).get(CHUNK_HASH_KEY) or _content_hash(document) if doc_hash not in combined.keys(): combined[doc_hash] = (distance, document, metadata) @@ -1267,7 +1267,7 @@ async def filter_accessible_collections( - any name with characters outside [A-Za-z0-9_-] → rejected - file-* → validated via has_access_to_file - user-memory-* → must match user's own memory collection - - web-search-* → ephemeral per-query collections, always allowed + - web-search-* → ephemeral per-query collections, owner-bound to web-search-{user.id}-* - knowledge-bases → always denied (system meta-collection) - everything else → if the name matches a knowledge base, validated via Knowledges.check_access_by_user_id; if no @@ -1302,10 +1302,10 @@ async def filter_accessible_collections( if name == f'user-memory-{user.id}': validated.add(name) elif name.startswith('web-search-'): - # Ephemeral collections created by process_web_search — safe - # to allow because they contain only transient web-search - # results scoped to the requesting user's session. - validated.add(name) + # Ephemeral per-query collections, owner-bound: process_web_search mints + # them as web-search-{user.id}-, so only the creator may read/write. + if name.startswith(f'web-search-{user.id}-'): + validated.add(name) else: # May be a knowledge-base ID or a legacy/ephemeral collection. # If it IS a KB, enforce access control. If no such KB @@ -1335,7 +1335,7 @@ async def get_sources_from_items( full_context=False, user: UserModel | None = None, ): - log.debug(f'items: {items} {queries} {embedding_function} {reranking_function} {full_context}') + log.debug('items: %s %s %s %s %s', items, queries, embedding_function, reranking_function, full_context) bypass_embedding_and_retrieval = await Config.get('rag.bypass_embedding_and_retrieval') extracted_collections = [] diff --git a/backend/open_webui/retrieval/vector/dbs/chroma.py b/backend/open_webui/retrieval/vector/dbs/chroma.py index 408a02111f..9780fcac60 100755 --- a/backend/open_webui/retrieval/vector/dbs/chroma.py +++ b/backend/open_webui/retrieval/vector/dbs/chroma.py @@ -3,6 +3,7 @@ from typing import Optional import chromadb from chromadb import Settings +from chromadb.errors import NotFoundError from chromadb.utils.batch_utils import create_batches from open_webui.config import ( CHROMA_CLIENT_AUTH_CREDENTIALS, @@ -56,13 +57,11 @@ class ChromaClient(VectorDBBase): ) def has_collection(self, collection_name: str) -> bool: - # Check if the collection exists based on the collection name. - # chromadb's list_collections() returns Collection objects (1.x), so a - # bare `name in collections` membership test is always False — compare - # against the names. (hasattr guard tolerates versions that yield names.) - collections = self.client.list_collections() - collection_names = [c.name if hasattr(c, 'name') else c for c in collections] - return collection_name in collection_names + try: + self.client.get_collection(name=collection_name) + return True + except NotFoundError: + return False def delete_collection(self, collection_name: str): # Delete the collection based on the collection name. diff --git a/backend/open_webui/retrieval/vector/dbs/milvus.py b/backend/open_webui/retrieval/vector/dbs/milvus.py index b0331e3eea..fa2abe85d7 100644 --- a/backend/open_webui/retrieval/vector/dbs/milvus.py +++ b/backend/open_webui/retrieval/vector/dbs/milvus.py @@ -25,7 +25,7 @@ from open_webui.retrieval.vector.main import ( VectorItem, ) from open_webui.retrieval.vector.utils import process_metadata -from pymilvus import Collection, DataType, FieldSchema, connections +from pymilvus import DataType from pymilvus import MilvusClient as Client from pymilvus.exceptions import MilvusException @@ -202,8 +202,6 @@ class MilvusClient(VectorDBBase): return self._result_to_search_result(result) def query(self, collection_name: str, filter: dict, limit: int = -1): - connections.connect(uri=MILVUS_URI, token=MILVUS_TOKEN, db_name=MILVUS_DB) - collection_name = collection_name.replace('-', '_') if not self.has_collection(collection_name): log.warning(f'Query attempted on non-existent collection: {self.collection_prefix}_{collection_name}') @@ -218,16 +216,16 @@ class MilvusClient(VectorDBBase): filter_string = ' && '.join(filter_expressions) - collection = Collection(f'{self.collection_prefix}_{collection_name}') - collection.load() + self.client.load_collection(collection_name=f'{self.collection_prefix}_{collection_name}') try: log.info( f"Querying collection {self.collection_prefix}_{collection_name} with filter: '{filter_string}', limit: {limit}" ) - iterator = collection.query_iterator( - expr=filter_string, + iterator = self.client.query_iterator( + collection_name=f'{self.collection_prefix}_{collection_name}', + filter=filter_string, output_fields=[ 'id', 'data', diff --git a/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py b/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py index f2f0b92817..599cb8712c 100644 --- a/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py +++ b/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py @@ -23,14 +23,8 @@ from open_webui.retrieval.vector.main import ( VectorDBBase, VectorItem, ) -from pymilvus import ( - Collection, - CollectionSchema, - DataType, - FieldSchema, - connections, - utility, -) +from pymilvus import DataType +from pymilvus import MilvusClient as Client from pymilvus.exceptions import MilvusException log = logging.getLogger(__name__) @@ -70,12 +64,7 @@ class MilvusClient(VectorDBBase): def __init__(self): # Milvus collection names can only contain numbers, letters, and underscores. self.collection_prefix = MILVUS_COLLECTION_PREFIX.replace('-', '_') - connections.connect( - alias='default', - uri=MILVUS_URI, - token=MILVUS_TOKEN, - db_name=MILVUS_DB, - ) + self.client = Client(uri=MILVUS_URI, token=MILVUS_TOKEN, db_name=MILVUS_DB) # Main collection types for multi-tenancy self.MEMORY_COLLECTION = f'{self.collection_prefix}_memories' @@ -116,63 +105,66 @@ class MilvusClient(VectorDBBase): return self.KNOWLEDGE_COLLECTION, resource_id def _create_shared_collection(self, mt_collection_name: str, dimension: int): - fields = [ - FieldSchema( - name='id', - dtype=DataType.VARCHAR, - is_primary=True, - auto_id=False, - max_length=36, - ), - FieldSchema(name='vector', dtype=DataType.FLOAT_VECTOR, dim=dimension), - FieldSchema(name='text', dtype=DataType.VARCHAR, max_length=65535), - FieldSchema(name='metadata', dtype=DataType.JSON), - FieldSchema(name=RESOURCE_ID_FIELD, dtype=DataType.VARCHAR, max_length=255), - ] - schema = CollectionSchema(fields, 'Shared collection for multi-tenancy') - collection = Collection(mt_collection_name, schema) + schema = self.client.create_schema(auto_id=False, description='Shared collection for multi-tenancy') + schema.add_field(field_name='id', datatype=DataType.VARCHAR, is_primary=True, max_length=36) + schema.add_field(field_name='vector', datatype=DataType.FLOAT_VECTOR, dim=dimension) + schema.add_field(field_name='text', datatype=DataType.VARCHAR, max_length=MILVUS_TEXT_MAX_LENGTH) + schema.add_field(field_name='metadata', datatype=DataType.JSON) + schema.add_field(field_name=RESOURCE_ID_FIELD, datatype=DataType.VARCHAR, max_length=255) - index_params = { - 'metric_type': MILVUS_METRIC_TYPE, - 'index_type': MILVUS_INDEX_TYPE, - 'params': {}, - } + index_build_params = {} if MILVUS_INDEX_TYPE == 'HNSW': - index_params['params'] = { + index_build_params = { 'M': MILVUS_HNSW_M, 'efConstruction': MILVUS_HNSW_EFCONSTRUCTION, } elif MILVUS_INDEX_TYPE == 'IVF_FLAT': - index_params['params'] = {'nlist': MILVUS_IVF_FLAT_NLIST} + index_build_params = {'nlist': MILVUS_IVF_FLAT_NLIST} - collection.create_index('vector', index_params) + vector_index = self.client.prepare_index_params( + field_name='vector', + index_type=MILVUS_INDEX_TYPE, + metric_type=MILVUS_METRIC_TYPE, + params=index_build_params, + ) + + self.client.create_collection(collection_name=mt_collection_name, schema=schema) + self.client.create_index(collection_name=mt_collection_name, index_params=vector_index) try: - # A Milvus server auto-selects the scalar index type; embedded - # Milvus Lite requires an explicit one. - collection.create_index(RESOURCE_ID_FIELD) + # A Milvus server auto-selects the scalar index type from a parameterless call. + self.client.create_index( + collection_name=mt_collection_name, + index_params=self.client.prepare_index_params(field_name=RESOURCE_ID_FIELD), + ) except MilvusException: try: - collection.create_index(RESOURCE_ID_FIELD, {'index_type': 'INVERTED'}) + self.client.create_index( + collection_name=mt_collection_name, + index_params=self.client.prepare_index_params(field_name=RESOURCE_ID_FIELD, index_type='INVERTED'), + ) except MilvusException as e: # The index only accelerates resource_id filters; never fail # collection creation over it. log.warning(f'Could not create {RESOURCE_ID_FIELD} index on {mt_collection_name}: {e}') log.info(f'Created shared collection: {mt_collection_name}') - return collection def _ensure_collection(self, mt_collection_name: str, dimension: int): - if not utility.has_collection(mt_collection_name): + if not self.client.has_collection(mt_collection_name): self._create_shared_collection(mt_collection_name, dimension) def has_collection(self, collection_name: str) -> bool: mt_collection, resource_id = self._get_collection_and_resource_id(collection_name) _validate_resource_id(resource_id) - if not utility.has_collection(mt_collection): + if not self.client.has_collection(mt_collection): return False - collection = Collection(mt_collection) - collection.load() - res = collection.query(expr=f"{RESOURCE_ID_FIELD} == '{resource_id}'", limit=1) + self.client.load_collection(mt_collection) + res = self.client.query( + collection_name=mt_collection, + filter=f"{RESOURCE_ID_FIELD} == '{resource_id}'", + output_fields=['id'], + limit=1, + ) return len(res) > 0 def upsert(self, collection_name: str, items: List[VectorItem]): @@ -182,7 +174,6 @@ class MilvusClient(VectorDBBase): _validate_resource_id(resource_id) dimension = len(items[0]['vector']) self._ensure_collection(mt_collection, dimension) - collection = Collection(mt_collection) entities = [] for item in items: @@ -205,7 +196,7 @@ class MilvusClient(VectorDBBase): ) try: - collection.insert(entities) + self.client.insert(collection_name=mt_collection, data=entities) except MilvusException as e: log.error( f'Milvus insert failed (collection={mt_collection}, ' @@ -225,19 +216,18 @@ class MilvusClient(VectorDBBase): mt_collection, resource_id = self._get_collection_and_resource_id(collection_name) _validate_resource_id(resource_id) - if not utility.has_collection(mt_collection): + if not self.client.has_collection(mt_collection): return None - collection = Collection(mt_collection) - collection.load() + self.client.load_collection(mt_collection) - search_params = {'metric_type': MILVUS_METRIC_TYPE, 'params': {}} - results = collection.search( + results = self.client.search( + collection_name=mt_collection, data=vectors, anns_field='vector', - param=search_params, + search_params={'metric_type': MILVUS_METRIC_TYPE, 'params': {}}, limit=limit, - expr=f"{RESOURCE_ID_FIELD} == '{resource_id}'", + filter=f"{RESOURCE_ID_FIELD} == '{resource_id}'", output_fields=['id', 'text', 'metadata'], ) @@ -245,10 +235,11 @@ class MilvusClient(VectorDBBase): for hits in results: batch_ids, batch_docs, batch_metadatas, batch_dists = [], [], [], [] for hit in hits: - batch_ids.append(hit.entity.get('id')) - batch_docs.append(hit.entity.get('text')) - batch_metadatas.append(hit.entity.get('metadata')) - batch_dists.append(hit.distance) + entity = hit.get('entity', {}) + batch_ids.append(entity.get('id')) + batch_docs.append(entity.get('text')) + batch_metadatas.append(entity.get('metadata')) + batch_dists.append(hit.get('distance')) ids.append(batch_ids) documents.append(batch_docs) metadatas.append(batch_metadatas) @@ -264,11 +255,9 @@ class MilvusClient(VectorDBBase): ): mt_collection, resource_id = self._get_collection_and_resource_id(collection_name) _validate_resource_id(resource_id) - if not utility.has_collection(mt_collection): + if not self.client.has_collection(mt_collection): return - collection = Collection(mt_collection) - expr = [f"{RESOURCE_ID_FIELD} == '{resource_id}'"] if ids: # Milvus expects a string list for 'in' operator @@ -280,30 +269,28 @@ class MilvusClient(VectorDBBase): _validate_metadata_key(key) expr.append(f"metadata['{key}'] == '{_escape_milvus_string(str(value))}'") - collection.delete(' and '.join(expr)) + self.client.delete(collection_name=mt_collection, filter=' and '.join(expr)) def reset(self): for collection_name in self.shared_collections: - if utility.has_collection(collection_name): - utility.drop_collection(collection_name) + if self.client.has_collection(collection_name): + self.client.drop_collection(collection_name) def delete_collection(self, collection_name: str): mt_collection, resource_id = self._get_collection_and_resource_id(collection_name) _validate_resource_id(resource_id) - if not utility.has_collection(mt_collection): + if not self.client.has_collection(mt_collection): return - collection = Collection(mt_collection) - collection.delete(f"{RESOURCE_ID_FIELD} == '{resource_id}'") + self.client.delete(collection_name=mt_collection, filter=f"{RESOURCE_ID_FIELD} == '{resource_id}'") def query(self, collection_name: str, filter: Dict[str, Any], limit: Optional[int] = None) -> Optional[GetResult]: mt_collection, resource_id = self._get_collection_and_resource_id(collection_name) _validate_resource_id(resource_id) - if not utility.has_collection(mt_collection): + if not self.client.has_collection(mt_collection): return None - collection = Collection(mt_collection) - collection.load() + self.client.load_collection(mt_collection) expr = [f"{RESOURCE_ID_FIELD} == '{resource_id}'"] if filter: @@ -318,8 +305,9 @@ class MilvusClient(VectorDBBase): else: raise TypeError(f'Unsupported Milvus filter value type for key {key!r}: {type(value).__name__}') - iterator = collection.query_iterator( - expr=' and '.join(expr), + iterator = self.client.query_iterator( + collection_name=mt_collection, + filter=' and '.join(expr), output_fields=['id', 'text', 'metadata'], limit=limit if limit else -1, ) diff --git a/backend/open_webui/retrieval/web/firecrawl.py b/backend/open_webui/retrieval/web/firecrawl.py index baffb6207d..04e03aff55 100644 --- a/backend/open_webui/retrieval/web/firecrawl.py +++ b/backend/open_webui/retrieval/web/firecrawl.py @@ -28,10 +28,10 @@ def build_firecrawl_url(base_url: str | None, path: str) -> str: def build_firecrawl_headers(api_key: str | None) -> dict[str, str]: - return { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {api_key or ""}', - } + headers = {'Content-Type': 'application/json'} + if api_key: + headers['Authorization'] = f'Bearer {api_key}' + return headers def get_firecrawl_timeout_seconds(timeout: Any) -> float | None: diff --git a/backend/open_webui/retrieval/web/main.py b/backend/open_webui/retrieval/web/main.py index 23cbf08aeb..d8127807cf 100644 --- a/backend/open_webui/retrieval/web/main.py +++ b/backend/open_webui/retrieval/web/main.py @@ -1,10 +1,11 @@ from __future__ import annotations +import ipaddress from urllib.parse import urlparse import validators from open_webui.retrieval.web.utils import resolve_hostname -from open_webui.utils.misc import is_host_allowed +from open_webui.utils.misc import get_allow_block_lists, is_host_allowed from pydantic import BaseModel @@ -12,6 +13,16 @@ def get_filtered_results(results, filter_list): if not filter_list: return results + allow_list, block_list = get_allow_block_lists(filter_list) + resolve_ips = False + for entry in allow_list + block_list: + try: + ipaddress.ip_address(entry) + except ValueError: + continue + resolve_ips = True + break + filtered_results = [] for result in results: @@ -25,12 +36,13 @@ def get_filtered_results(results, filter_list): hostnames = [domain] - try: - ipv4_addresses, ipv6_addresses = resolve_hostname(domain) - hostnames.extend(ipv4_addresses) - hostnames.extend(ipv6_addresses) - except Exception: - pass + if resolve_ips: + try: + ipv4_addresses, ipv6_addresses = resolve_hostname(domain) + hostnames.extend(ipv4_addresses) + hostnames.extend(ipv6_addresses) + except Exception: + pass if is_host_allowed(hostnames, filter_list): filtered_results.append(result) diff --git a/backend/open_webui/retrieval/web/openserp.py b/backend/open_webui/retrieval/web/openserp.py new file mode 100644 index 0000000000..a9276cb1a0 --- /dev/null +++ b/backend/open_webui/retrieval/web/openserp.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +import logging + +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.utils.session_pool import get_session + +log = logging.getLogger(__name__) + + +async def search_openserp( + base_url: str, + query: str, + count: int, + filter_list: list[str | None] | None = None, +) -> list[SearchResult]: + """Query an OpenSERP instance and return normalised results. + + OpenSERP aggregates results from 6 engines (google, bing, yandex, + baidu, duckduckgo, ecosia) at once via ``/mega/search``. + + No API key is required -- only a reachable OpenSERP base URL. + """ + url = f'{base_url.rstrip("/")}/mega/search' + params = {'text': query, 'limit': count} + + log.debug('searching OpenSERP at %s', url) + + session = await get_session() + async with session.get(url, params=params) as response: + response.raise_for_status() + payload = await response.json() + + results = payload.get('results', []) + if filter_list: + results = get_filtered_results(results, filter_list) + + return [ + SearchResult( + link=item.get('url', ''), + title=item.get('title'), + snippet=item.get('snippet'), + ) + for item in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/searxng.py b/backend/open_webui/retrieval/web/searxng.py index 9c48b0f1b3..6b1c03cdd3 100644 --- a/backend/open_webui/retrieval/web/searxng.py +++ b/backend/open_webui/retrieval/web/searxng.py @@ -1,7 +1,10 @@ from __future__ import annotations import logging +import ssl +from functools import lru_cache +from open_webui.env import AIOHTTP_CLIENT_SESSION_SSL, SEARXNG_CLIENT_CERT_FILE, SEARXNG_CLIENT_KEY_FILE from open_webui.retrieval.web.main import SearchResult, get_filtered_results from open_webui.utils.session_pool import get_session @@ -17,6 +20,19 @@ _SEARXNG_HEADERS = { } +@lru_cache +def _get_ssl_context() -> bool | ssl.SSLContext: + if not SEARXNG_CLIENT_CERT_FILE: + return AIOHTTP_CLIENT_SESSION_SSL + + ssl_context = ssl.create_default_context() + ssl_context.load_cert_chain( + certfile=SEARXNG_CLIENT_CERT_FILE, + keyfile=SEARXNG_CLIENT_KEY_FILE or None, + ) + return ssl_context + + async def search_searxng( query_url: str, query: str, @@ -48,7 +64,12 @@ async def search_searxng( log.debug('searching %s', query_url) session = await get_session() - async with session.get(query_url, headers=_SEARXNG_HEADERS, params=params) as response: + async with session.get( + query_url, + headers=_SEARXNG_HEADERS, + params=params, + ssl=_get_ssl_context(), + ) as response: response.raise_for_status() payload = await response.json() diff --git a/backend/open_webui/retrieval/web/utils.py b/backend/open_webui/retrieval/web/utils.py index 22fe7d98ae..5d143e9d5c 100644 --- a/backend/open_webui/retrieval/web/utils.py +++ b/backend/open_webui/retrieval/web/utils.py @@ -3,9 +3,10 @@ import ipaddress import logging import socket import ssl +import time import urllib.parse import urllib.request -from datetime import datetime, time, timedelta +from datetime import datetime, timedelta from typing import ( Any, AsyncIterator, @@ -74,6 +75,34 @@ def resolve_hostname(hostname): return ipv4_addresses, ipv6_addresses +def _is_global_addr(ip: str) -> bool: + addr = ipaddress.ip_address(ip) + if not addr.is_global: + return False + if not isinstance(addr, ipaddress.IPv6Address): + return True + + embedded = [] + if addr.ipv4_mapped: + embedded.append(addr.ipv4_mapped) + if addr.sixtofour: + embedded.append(addr.sixtofour) + if addr.teredo: + embedded.extend(addr.teredo) + + b = addr.packed + if b[:12] == b"\x00" * 12: + embedded.append(ipaddress.IPv4Address(b[12:])) + elif b[:12] == b"\x00\x64\xff\x9b" + b"\x00" * 8: + embedded.append(ipaddress.IPv4Address(b[12:])) + elif b[:6] == b"\x00\x64\xff\x9b\x00\x01": + if b[8] != 0: + return False + embedded.append(ipaddress.IPv4Address(bytes((b[6], b[7], b[9], b[10])))) + + return all(ip.is_global for ip in embedded) + + def validate_url(url: Union[str, Sequence[str]]): if isinstance(url, str): if isinstance(validators.url(url), validators.ValidationError): @@ -110,8 +139,7 @@ def validate_url(url: Union[str, Sequence[str]]): # Check if any of the resolved addresses are private # DNS rebinding is mitigated at the connection layer; see _SSRFSafeResolver / _SSRFSafeAdapter for ip in ipv4_addresses + ipv6_addresses: - addr = ipaddress.ip_address(ip) - if not addr.is_global: + if not _is_global_addr(ip): raise ValueError(ERROR_MESSAGES.INVALID_URL) return True elif isinstance(url, Sequence): @@ -146,7 +174,7 @@ def _ssrf_safe_new_conn(self): raise OSError(f'getaddrinfo for {host!r} returned empty list') if not ENABLE_LOCAL_WEB_FETCH: for _, _, _, _, sa in infos: - if not ipaddress.ip_address(sa[0]).is_global: + if not _is_global_addr(sa[0]): raise ValueError(ERROR_MESSAGES.INVALID_URL) err = None for fam, typ, proto, _, sa in infos: @@ -207,7 +235,7 @@ class _SSRFSafeResolver(aiohttp.resolver.DefaultResolver): results = await super().resolve(host, port, family) if not ENABLE_LOCAL_WEB_FETCH: for entry in results: - if not ipaddress.ip_address(entry['host']).is_global: + if not _is_global_addr(entry['host']): raise ValueError(ERROR_MESSAGES.INVALID_URL) return results @@ -605,57 +633,63 @@ class SafePlaywrightURLLoader(PlaywrightURLLoader, RateLimitMixin, URLProcessing def _intercept_navigation_sync(self, route, request=None): req = request or route.request - if req.resource_type != 'document': - route.continue_() - return - try: validate_url(req.url) + resp = route.fetch(max_redirects=0) + + if 300 <= resp.status < 400: + for _ in range(20): + if not AIOHTTP_CLIENT_ALLOW_REDIRECTS: + route.abort() + return + + location = resp.headers.get('location') + if not location: + break + + url = urllib.parse.urljoin(resp.url, location) + validate_url(url) + resp = route.fetch(url=url, max_redirects=0) + if not 300 <= resp.status < 400: + break + else: + route.abort() + return except Exception: route.abort() return - if AIOHTTP_CLIENT_ALLOW_REDIRECTS: - resp = route.fetch() - else: - try: - resp = route.fetch(max_redirects=0) - except TypeError: - route.abort() - return - - if 300 <= resp.status < 400: - route.abort() - return - route.fulfill(response=resp) async def _intercept_navigation(self, route, request=None): req = request or route.request - if req.resource_type != 'document': - await route.continue_() - return - try: await run_in_threadpool(validate_url, req.url) + resp = await route.fetch(max_redirects=0) + + if 300 <= resp.status < 400: + for _ in range(20): + if not AIOHTTP_CLIENT_ALLOW_REDIRECTS: + await route.abort() + return + + location = resp.headers.get('location') + if not location: + break + + url = urllib.parse.urljoin(resp.url, location) + await run_in_threadpool(validate_url, url) + resp = await route.fetch(url=url, max_redirects=0) + if not 300 <= resp.status < 400: + break + else: + await route.abort() + return except Exception: await route.abort() return - if AIOHTTP_CLIENT_ALLOW_REDIRECTS: - resp = await route.fetch() - else: - try: - resp = await route.fetch(max_redirects=0) - except TypeError: - await route.abort() - return - - if 300 <= resp.status < 400: - await route.abort() - return - await route.fulfill(response=resp) def lazy_load(self) -> Iterator[Document]: @@ -669,24 +703,25 @@ class SafePlaywrightURLLoader(PlaywrightURLLoader, RateLimitMixin, URLProcessing else: browser = p.chromium.launch(headless=self.headless, proxy=self.proxy) - for url in self.urls: - try: - self._safe_process_url_sync(url) - page = browser.new_page() - page.route('**/*', self._intercept_navigation_sync) - response = page.goto(url, timeout=self.playwright_timeout) - if response is None: - raise ValueError(f'page.goto() returned None for url {url}') + with browser: + for url in self.urls: + try: + self._safe_process_url_sync(url) + with browser.new_page(service_workers='block') as page: + page.route('**/*', self._intercept_navigation_sync) + page.route_web_socket('**/*', lambda ws_route: ws_route.close()) + response = page.goto(url, timeout=self.playwright_timeout) + if response is None: + raise ValueError(f'page.goto() returned None for url {url}') - text = self.evaluator.evaluate(page, browser, response) - metadata = {'source': url} - yield Document(page_content=text, metadata=metadata) - except Exception as e: - if self.continue_on_failure: - log.exception(f'Error loading {url}: {e}') - continue - raise e - browser.close() + text = self.evaluator.evaluate(page, browser, response) + metadata = {'source': url} + yield Document(page_content=text, metadata=metadata) + except Exception as e: + if self.continue_on_failure: + log.exception(f'Error loading {url}: {e}') + continue + raise e async def alazy_load(self) -> AsyncIterator[Document]: """Safely load URLs asynchronously with support for remote browser.""" @@ -699,24 +734,25 @@ class SafePlaywrightURLLoader(PlaywrightURLLoader, RateLimitMixin, URLProcessing else: browser = await p.chromium.launch(headless=self.headless, proxy=self.proxy) - for url in self.urls: - try: - await self._safe_process_url(url) - page = await browser.new_page() - await page.route('**/*', self._intercept_navigation) - response = await page.goto(url, timeout=self.playwright_timeout) - if response is None: - raise ValueError(f'page.goto() returned None for url {url}') + async with browser: + for url in self.urls: + try: + await self._safe_process_url(url) + async with await browser.new_page(service_workers='block') as page: + await page.route('**/*', self._intercept_navigation) + await page.route_web_socket('**/*', lambda ws_route: ws_route.close()) + response = await page.goto(url, timeout=self.playwright_timeout) + if response is None: + raise ValueError(f'page.goto() returned None for url {url}') - text = await self.evaluator.evaluate_async(page, browser, response) - metadata = {'source': url} - yield Document(page_content=text, metadata=metadata) - except Exception as e: - if self.continue_on_failure: - log.exception(f'Error loading {url}: {e}') - continue - raise e - await browser.close() + text = await self.evaluator.evaluate_async(page, browser, response) + metadata = {'source': url} + yield Document(page_content=text, metadata=metadata) + except Exception as e: + if self.continue_on_failure: + log.exception(f'Error loading {url}: {e}') + continue + raise e class SafeWebBaseLoader(WebBaseLoader): @@ -728,6 +764,8 @@ class SafeWebBaseLoader(WebBaseLoader): trust_env (bool, optional): set to True if using proxy to make web requests, for example using http(s)_proxy environment variables. Defaults to False. """ + # lxml parses scraped pages far faster than the html.parser default + kwargs.setdefault('default_parser', 'lxml') super().__init__(*args, **kwargs) self.trust_env = trust_env @@ -797,11 +835,6 @@ class SafeWebBaseLoader(WebBaseLoader): final_results.append(BeautifulSoup(result, url_parser, **self.bs_kwargs)) return final_results - async def ascrape_all(self, urls: List[str], parser: Union[str, None] = None) -> List[Any]: - """Async fetch all urls, then return soups for all results.""" - results = await self.fetch_all(urls) - return self._unpack_fetch_results(results, urls, parser=parser) - def lazy_load(self) -> Iterator[Document]: """Lazy load text from the url(s) in web_path with error handling.""" for path in self.web_paths: @@ -817,19 +850,20 @@ class SafeWebBaseLoader(WebBaseLoader): # Log the error and continue with the next URL log.exception(f'Error loading {path}: {e}') + def _document_from_html(self, html: str, url: str) -> Document: + """Build one Document.""" + soup = self._unpack_fetch_results([html], [url])[0] + return Document( + page_content=soup.get_text(**self.bs_get_text_kwargs), + metadata=extract_metadata(soup, url), + ) + async def alazy_load(self) -> AsyncIterator[Document]: """Async lazy load text from the url(s) in web_path.""" - results = await self.ascrape_all(self.web_paths) - for path, soup in zip(self.web_paths, results): - text = soup.get_text(**self.bs_get_text_kwargs) - metadata = {'source': path} - if title := soup.find('title'): - metadata['title'] = title.get_text() - if description := soup.find('meta', attrs={'name': 'description'}): - metadata['description'] = description.get('content', 'No description found.') - if html := soup.find('html'): - metadata['language'] = html.get('lang', 'No language found.') - yield Document(page_content=text, metadata=metadata) + results = await self.fetch_all(self.web_paths) + for path, html in zip(self.web_paths, results): + # parsing a large page costs hundreds of ms, keep it off the event loop + yield await asyncio.to_thread(self._document_from_html, html, path) async def aload(self) -> list[Document]: """Load data into Document objects.""" diff --git a/backend/open_webui/routers/audio.py b/backend/open_webui/routers/audio.py index 1599852f3c..17bb32f35c 100644 --- a/backend/open_webui/routers/audio.py +++ b/backend/open_webui/routers/audio.py @@ -1091,19 +1091,17 @@ async def transcribe(request: Request, file_path: str, metadata: Optional[dict] detail=ERROR_MESSAGES.DEFAULT(e, 'Error processing audio file'), ) - results = [] try: tasks = [transcription_handler(request, chunk_path, metadata, user) for chunk_path in chunk_paths] - for coro in asyncio.as_completed(tasks): - try: - results.append(await coro) - except HTTPException: - raise - except Exception as transcribe_exc: - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f'Error transcribing chunk: {transcribe_exc}', - ) + # gather keeps results in chunk order, unlike as_completed + results = await asyncio.gather(*tasks) + except HTTPException: + raise + except Exception as transcribe_exc: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'Error transcribing chunk: {transcribe_exc}', + ) finally: # Clean up only the temporary chunks, never the original file for chunk_path in chunk_paths: diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py index fbb7b2d99f..e0899da786 100644 --- a/backend/open_webui/routers/auths.py +++ b/backend/open_webui/routers/auths.py @@ -26,6 +26,8 @@ from open_webui.env import ( ENABLE_INITIAL_ADMIN_SIGNUP, ENABLE_OAUTH_TOKEN_EXCHANGE, OAUTH_TOKEN_EXCHANGE_ALLOWED_AUDIENCES, + OAUTH_TOKEN_EXCHANGE_RATE_LIMIT, + OAUTH_TOKEN_EXCHANGE_RATE_LIMIT_WINDOW, WEBUI_AUTH, WEBUI_AUTH_COOKIE_SAME_SITE, WEBUI_AUTH_COOKIE_SECURE, @@ -85,6 +87,17 @@ log = logging.getLogger(__name__) # Forgive us our failed attempts, as we forgive those # who exceed their allotted rate against this gate. signin_rate_limiter = RateLimiter(redis_client=get_redis_client(), limit=5 * 3, window=60 * 3) +# Best-effort throttle only: there is no caller identity before the provider answers, +# and deployments may derive request.client from proxy headers. +token_exchange_rate_limiter = ( + RateLimiter( + redis_client=get_redis_client(), + limit=OAUTH_TOKEN_EXCHANGE_RATE_LIMIT, + window=OAUTH_TOKEN_EXCHANGE_RATE_LIMIT_WINDOW, + ) + if OAUTH_TOKEN_EXCHANGE_RATE_LIMIT is not None + else None +) ADMIN_CONFIG_KEYS = { 'SHOW_ADMIN_DETAILS': 'auth.admin.show', @@ -105,6 +118,7 @@ ADMIN_CONFIG_KEYS = { 'AUTOMATION_MIN_INTERVAL': 'automations.min_interval', 'ENABLE_AUTOMATIONS': 'automations.enable', 'ENABLE_CHANNELS': 'channels.enable', + 'CHANNEL_MODEL_RESPONSE_MODE': 'channels.model_response_mode', 'ENABLE_CALENDAR': 'calendar.enable', 'ENABLE_MEMORIES': 'memories.enable', 'ENABLE_MEMORY_SYSTEM_CONTEXT': 'memories.system_context.enable', @@ -1185,6 +1199,7 @@ class AdminConfig(BaseModel): AUTOMATION_MIN_INTERVAL: int | str | None = None ENABLE_AUTOMATIONS: bool ENABLE_CHANNELS: bool + CHANNEL_MODEL_RESPONSE_MODE: str = 'thread' ENABLE_CALENDAR: bool ENABLE_MEMORIES: bool ENABLE_MEMORY_SYSTEM_CONTEXT: bool @@ -1208,6 +1223,9 @@ async def update_admin_config(request: Request, form_data: AdminConfig, user=Dep if form_data.DEFAULT_USER_ROLE not in ['pending', 'user', 'admin']: updates.pop('ui.default_user_role', None) + if form_data.CHANNEL_MODEL_RESPONSE_MODE not in ['thread', 'channel']: + updates.pop('channels.model_response_mode', None) + pattern = r'^(-1|0|(-?\d+(\.\d+)?)(ms|s|m|h|d|w))$' # Check if the input string matches the pattern @@ -1292,6 +1310,7 @@ class OAuthConfigForm(BaseModel): """All OAuth/OIDC settings exposed to the admin panel.""" # General OAuth + ENABLE_OAUTH: bool | None = None ENABLE_OAUTH_SIGNUP: bool | None = None OAUTH_MERGE_ACCOUNTS_BY_EMAIL: bool | None = None OAUTH_AUTO_REDIRECT: bool | None = None @@ -1347,6 +1366,7 @@ OAUTH_COMMA_LIST_FIELDS = { OAUTH_CONFIG_KEYS = { + 'ENABLE_OAUTH': 'oauth.enable', 'ENABLE_OAUTH_SIGNUP': 'oauth.enable_signup', 'OAUTH_MERGE_ACCOUNTS_BY_EMAIL': 'oauth.merge_accounts_by_email', 'OAUTH_AUTO_REDIRECT': 'oauth.auto_redirect', @@ -1552,6 +1572,14 @@ async def token_exchange( detail='Token exchange is disabled', ) + if token_exchange_rate_limiter and token_exchange_rate_limiter.is_limited( + request.client.host if request.client else 'unknown' + ): + raise HTTPException( + status_code=status.HTTP_429_TOO_MANY_REQUESTS, + detail=ERROR_MESSAGES.RATE_LIMIT_EXCEEDED, + ) + provider = provider.lower() # Check if provider is configured diff --git a/backend/open_webui/routers/automations.py b/backend/open_webui/routers/automations.py index f7d027bad9..e01c5c255b 100644 --- a/backend/open_webui/routers/automations.py +++ b/backend/open_webui/routers/automations.py @@ -16,6 +16,7 @@ from open_webui.models.automations import ( Automations, ) from open_webui.models.config import Config +from open_webui.models.folders import Folders from open_webui.utils.access_control import has_permission from open_webui.utils.auth import get_admin_user, get_verified_user from open_webui.utils.automations import ( @@ -56,16 +57,11 @@ async def check_automations_permission(request, user): def check_automation_access(automation, user): - if not automation: + if not automation or user.id != automation.user_id: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND, ) - if user.role != 'admin' and user.id != automation.user_id: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail=ERROR_MESSAGES.UNAUTHORIZED, - ) async def check_automation_limits(request, user, rrule_str: str, db, is_create: bool = False): @@ -97,6 +93,17 @@ async def check_automation_limits(request, user, rrule_str: str, db, is_create: ) +async def check_automation_folder_access(folder_id: Optional[str], user, db: AsyncSession): + if folder_id is None: + return + folder = await Folders.get_folder_by_id_and_user_id(folder_id, user.id, db=db) + if not folder: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + async def enrich_automation(automation: AutomationModel, db: AsyncSession, tz: str = None) -> AutomationResponse: """Full enrichment for single-item views (includes next_runs computation).""" last_run = await AutomationRuns.get_latest(automation.id, db=db) @@ -117,6 +124,7 @@ async def get_automation_items( request: Request, query: Optional[str] = None, status: Optional[str] = None, + folder_id: Optional[str] = None, page: Optional[int] = 1, user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session), @@ -130,6 +138,7 @@ async def get_automation_items( user_id=user.id, query=query, status=status, + folder_id=folder_id, skip=skip, limit=limit, db=db, @@ -164,6 +173,7 @@ async def create_new_automation( db: AsyncSession = Depends(get_async_session), ): await check_automations_permission(request, user) + await check_automation_folder_access(form_data.folder_id, user, db) try: validate_rrule(form_data.data.rrule, tz=user.timezone) except ValueError as e: @@ -182,7 +192,7 @@ async def create_new_automation( EVENTS.AUTOMATION_CREATED, actor=user, subject_id=automation.id, - data={'name': automation.name, 'is_active': automation.is_active}, + data={'name': automation.name, 'is_active': automation.is_active, 'folder_id': automation.folder_id}, ) return response @@ -221,6 +231,7 @@ async def update_automation_by_id( await check_automations_permission(request, user) automation = await Automations.get_by_id(id, db=db) check_automation_access(automation, user) + await check_automation_folder_access(form_data.folder_id, user, db) try: validate_rrule(form_data.data.rrule, tz=user.timezone) @@ -240,7 +251,7 @@ async def update_automation_by_id( EVENTS.AUTOMATION_UPDATED, actor=user, subject_id=updated.id, - data={'name': updated.name, 'is_active': updated.is_active}, + data={'name': updated.name, 'is_active': updated.is_active, 'folder_id': updated.folder_id}, ) return response diff --git a/backend/open_webui/routers/channels.py b/backend/open_webui/routers/channels.py index 64413fa74e..7bef2eb9d8 100644 --- a/backend/open_webui/routers/channels.py +++ b/backend/open_webui/routers/channels.py @@ -987,13 +987,18 @@ async def model_response_handler(request, channel, message, user, db=None): db=db, ) )[::-1] + response_parent_id = ( + message.parent_id + if message.parent_id + else (message.id if await Config.get('channels.model_response_mode', 'thread') == 'thread' else None) + ) response_message, channel = await new_message_handler( request, channel.id, MessageForm( **{ - 'parent_id': (message.parent_id if message.parent_id else message.id), + 'parent_id': response_parent_id, 'content': f'', 'data': {}, 'meta': { diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index 1a707607e0..e618eb3f06 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -6,8 +6,9 @@ import logging from typing import Optional from uuid import uuid4 -from fastapi import APIRouter, Depends, HTTPException, Request, status +from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Request, Response, status from fastapi.responses import StreamingResponse +from fastapi.security import HTTPAuthorizationCredentials from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT from open_webui.constants import ERROR_MESSAGES from open_webui.events import EVENTS, publish_event @@ -37,7 +38,7 @@ from open_webui.socket.main import get_event_emitter from open_webui.tasks import has_active_tasks, stop_item_tasks from open_webui.utils.access_control import filter_allowed_access_grants, has_permission from open_webui.utils.access_control.folders import has_folder_access -from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.auth import bearer_security, get_admin_user, get_current_user, get_verified_user from open_webui.utils.chat_fork import build_fork_history from open_webui.utils.context_compaction import compact_chat_branch, get_chat_context_usage from open_webui.utils.misc import get_message_list @@ -52,6 +53,7 @@ router = APIRouter() SEARCH_FILTER_PREFIXES = ('tag:', 'folder:', 'pinned:', 'archived:', 'shared:') CHAT_CONFIG_KEYS = { + 'CONTEXT_COMPACTION_MODEL': 'chat.context_compaction.model', 'ENABLE_CONTEXT_COMPACTION': 'chat.context_compaction.enable', 'CONTEXT_COMPACTION_TOKEN_THRESHOLD': 'chat.context_compaction.token_threshold', 'CONTEXT_COMPACTION_TOKEN_CAP': 'chat.context_compaction.token_cap', @@ -60,6 +62,47 @@ CHAT_CONFIG_KEYS = { } +async def get_optional_verified_user( + request: Request, + response: Response, + background_tasks: BackgroundTasks, + auth_token: HTTPAuthorizationCredentials | None = Depends(bearer_security), +): + try: + user = await get_current_user(request, response, background_tasks, auth_token) + except HTTPException: + return None + + if user.role not in {'user', 'admin'}: + return None + return user + + +async def is_open_shared_chat(shared, db: AsyncSession) -> bool: + return await AccessGrants.has_anyone_access( + resource_type='shared_chat', + resource_id=shared.chat_id, + permission='read', + db=db, + ) + + +async def can_read_shared_chat(user, shared, db: AsyncSession) -> bool: + if user.role == 'pending': + return False + if user.role == 'admin' and ENABLE_ADMIN_CHAT_ACCESS: + return True + if shared.user_id == user.id: + return True + return await AccessGrants.has_access( + user_id=user.id, + resource_type='shared_chat', + resource_id=shared.chat_id, + permission='read', + db=db, + ) + + async def add_active_state_to_chat_list( request: Request, chat_list: list[ChatTitleIdResponse] ) -> list[ChatTitleIdResponse]: @@ -73,7 +116,26 @@ async def add_active_state_to_chat_list( return chat_list +async def get_folder_unread_counts(user_id: str, db: AsyncSession | None = None) -> dict[str, int]: + user_folders = await Folders.get_folders_by_user_id(user_id, db=db) + parent_by_id = {folder.id: folder.parent_id for folder in user_folders} + unread_counts = dict.fromkeys(parent_by_id.keys(), 0) + direct_unread_counts = await Chats.count_unread_by_folder_ids(user_id, list(parent_by_id.keys()), db=db) + + for unread_folder_id, unread_count in direct_unread_counts.items(): + current_id = unread_folder_id + seen = set() + while current_id and current_id not in seen: + seen.add(current_id) + if current_id in unread_counts: + unread_counts[current_id] += unread_count + current_id = parent_by_id.get(current_id) + + return unread_counts + + class ChatConfigForm(BaseModel): + CONTEXT_COMPACTION_MODEL: str | None = '' ENABLE_CONTEXT_COMPACTION: bool CONTEXT_COMPACTION_TOKEN_THRESHOLD: int CONTEXT_COMPACTION_TOKEN_CAP: int | None = None @@ -125,6 +187,8 @@ def chat_search_snippet(chat: dict, search_text: str, max_length: int = 200) -> async def get_chat_config_values() -> dict: values = await Config.get_many(*CHAT_CONFIG_KEYS.values()) config = {field: values[storage_key] for field, storage_key in CHAT_CONFIG_KEYS.items() if storage_key in values} + if config.get('CONTEXT_COMPACTION_MODEL') is None: + config['CONTEXT_COMPACTION_MODEL'] = '' if config.get('CONTEXT_COMPACTION_TOKEN_CAP') is None: config['CONTEXT_COMPACTION_TOKEN_CAP'] = config.get('CONTEXT_COMPACTION_TOKEN_THRESHOLD', 80000) if config.get('CONTEXT_COMPACTION_RETENTION_PERCENTAGE') is None: @@ -161,6 +225,8 @@ async def get_session_user_chat_list( page: int | None = None, include_pinned: bool | None = False, include_folders: bool | None = False, + sort_by: str = 'updated_at', + sort_dir: str = 'desc', db: AsyncSession = Depends(get_async_session), ): try: @@ -172,6 +238,8 @@ async def get_session_user_chat_list( user.id, include_folders=include_folders, include_pinned=include_pinned, + sort_by=sort_by, + sort_dir=sort_dir, skip=skip, limit=limit, db=db, @@ -181,6 +249,8 @@ async def get_session_user_chat_list( user.id, include_folders=include_folders, include_pinned=include_pinned, + sort_by=sort_by, + sort_dir=sort_dir, db=db, ) return await add_active_state_to_chat_list(request, chats) @@ -189,6 +259,17 @@ async def get_session_user_chat_list( raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()) +@router.post('/read') +async def mark_chats_read_by_user_id( + user=Depends(get_verified_user), + db: AsyncSession = Depends(get_async_session), +): + return { + 'updated_count': await Chats.mark_chats_read_by_user_id(user.id, db=db), + 'folder_unread_counts': await get_folder_unread_counts(user.id, db=db), + } + + ############################ # GetChatUsageStats # EXPERIMENTAL: may be removed in future releases @@ -693,7 +774,7 @@ async def create_new_chat( subject_id=chat.id, data={'title': chat.title, 'folder_id': chat.folder_id}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) except Exception as e: log.exception(e) raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()) @@ -747,6 +828,7 @@ async def set_chat_config(form_data: ChatConfigForm, user=Depends(get_admin_user chat_config_updates( { **form_data.model_dump(), + 'CONTEXT_COMPACTION_MODEL': form_data.CONTEXT_COMPACTION_MODEL or '', 'CONTEXT_COMPACTION_TOKEN_THRESHOLD': threshold, 'CONTEXT_COMPACTION_TOKEN_CAP': token_cap, 'CONTEXT_COMPACTION_RETENTION_PERCENTAGE': retention_percentage, @@ -778,7 +860,17 @@ async def search_user_chats( search_text = chat_search_content_text(text) chat_list = [] for chat in await Chats.get_chats_by_user_id_and_search_text(user.id, text, skip=skip, limit=limit, db=db): - chat_list.append(ChatTitleIdResponse(**chat.model_dump(), snippet=chat_search_snippet(chat.chat, search_text))) + # Explicit fields: model_dump() would deep-copy the entire chat blob per row + chat_list.append( + ChatTitleIdResponse( + id=chat.id, + title=chat.title, + updated_at=chat.updated_at, + created_at=chat.created_at, + last_read_at=chat.last_read_at, + snippet=chat_search_snippet(chat.chat, search_text), + ) + ) # Delete tag if no chat is found words = text.strip().split(' ') @@ -807,7 +899,7 @@ async def get_chats_by_folder_id( folder_ids.extend([folder.id for folder in children_folders]) return [ - ChatResponse(**chat.model_dump()) + ChatResponse.model_validate(chat, from_attributes=True) for chat in await Chats.get_chats_by_folder_ids_and_user_id(folder_ids, user.id, db=db) ] @@ -817,6 +909,8 @@ async def get_chat_list_by_folder_id( request: Request, folder_id: str, page: int | None = 1, + sort_by: str = 'unread_updated_at', + sort_dir: str = 'desc', user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session), ): @@ -824,7 +918,15 @@ async def get_chat_list_by_folder_id( limit = 10 skip = (page - 1) * limit - chats = await Chats.get_chats_by_folder_id_and_user_id(folder_id, user.id, skip=skip, limit=limit, db=db) + chats = await Chats.get_chats_by_folder_id_and_user_id( + folder_id, + user.id, + skip=skip, + limit=limit, + sort_by=sort_by, + sort_dir=sort_dir, + db=db, + ) return await add_active_state_to_chat_list(request, chats) except Exception as e: @@ -873,7 +975,7 @@ async def generate_chat_export_ndjson(user_id: str): for chat in result.items: try: - yield ChatResponse(**chat.model_dump()).model_dump_json() + '\n' + yield ChatResponse.model_validate(chat, from_attributes=True).model_dump_json() + '\n' except Exception as e: log.exception(f'Error serializing chat {chat.id}: {e}') @@ -898,7 +1000,10 @@ async def get_user_chats(user=Depends(get_verified_user)): @router.get('/all/archived', response_model=list[ChatResponse]) async def get_user_archived_chats(user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session)): - return [ChatResponse(**chat.model_dump()) for chat in await Chats.get_archived_chats_by_user_id(user.id, db=db)] + return [ + ChatResponse.model_validate(chat, from_attributes=True) + for chat in await Chats.get_archived_chats_by_user_id(user.id, db=db) + ] ############################ @@ -925,7 +1030,7 @@ async def get_all_user_tags(user=Depends(get_verified_user), db: AsyncSession = async def get_all_user_chats_in_db(user=Depends(get_admin_user), db: AsyncSession = Depends(get_async_session)): if not ENABLE_ADMIN_EXPORT: raise HTTPException(status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.ACCESS_PROHIBITED) - return [ChatResponse(**chat.model_dump()) for chat in await Chats.get_chats(db=db)] + return [ChatResponse.model_validate(chat, from_attributes=True) for chat in await Chats.get_chats(db=db)] ############################ @@ -1082,38 +1187,30 @@ async def get_shared_session_user_chat_list( @router.get('/share/{share_id}', response_model=ChatResponse | None) async def get_shared_chat_by_id( - share_id: str, user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session) + share_id: str, user=Depends(get_optional_verified_user), db: AsyncSession = Depends(get_async_session) ): - if user.role == 'pending': - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND) + shared = await SharedChats.get_by_id(share_id, db=db) + if shared: + if await is_open_shared_chat(shared, db=db) or ( + user is not None and await can_read_shared_chat(user, shared, db=db) + ): + chat = await Chats.get_chat_by_share_id(share_id, db=db) + if chat: + return ChatResponse.model_validate(chat, from_attributes=True) - chat = await Chats.get_chat_by_share_id(share_id, db=db) + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED if user else ERROR_MESSAGES.INVALID_TOKEN, + ) # Fallback: admins can also access any chat directly by chat ID - if not chat and user.role == 'admin' and ENABLE_ADMIN_CHAT_ACCESS: + chat = None + if user is not None and user.role == 'admin' and ENABLE_ADMIN_CHAT_ACCESS: chat = await Chats.get_chat_by_id(share_id, db=db) + if chat: + return ChatResponse.model_validate(chat, from_attributes=True) - if not chat: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND) - - # Look up the original chat_id to check access grants (admins bypass) - if user.role != 'admin' or not ENABLE_ADMIN_CHAT_ACCESS: - shared = await SharedChats.get_by_id(share_id, db=db) - if shared and shared.user_id != user.id: - has_grant = await AccessGrants.has_access( - user_id=user.id, - resource_type='shared_chat', - resource_id=shared.chat_id, - permission='read', - db=db, - ) - if not has_grant: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail=ERROR_MESSAGES.ACCESS_PROHIBITED, - ) - - return ChatResponse(**chat.model_dump()) + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND) ############################ @@ -1236,7 +1333,7 @@ async def get_chat_by_id(id: str, user=Depends(get_verified_user), db: AsyncSess chat = candidate if chat: - data = ChatResponse(**chat.model_dump()).model_dump() + data = ChatResponse.model_validate(chat, from_attributes=True).model_dump() data['context_usage'] = await get_chat_context_usage(chat) return data @@ -1265,9 +1362,18 @@ async def update_chat_by_id( form_data.chat.get('history'), ) - chat = await Chats.update_chat_by_id(id, updated_chat, db=db) + touch = 'history' in form_data.chat or 'messages' in form_data.chat + chat = await Chats.update_chat_by_id(id, updated_chat, db=db, touch=touch) if form_data.variables is not None: - chat = await Chats.update_chat_variables_by_id(id, form_data.variables, db=db) or chat + chat = ( + await Chats.update_chat_variables_by_id( + id, + form_data.variables, + db=db, + touch=False, + ) + or chat + ) # Reconcile chat_message rows without inferring deletes from missing IDs. # Message deletion has its own endpoint below. @@ -1282,7 +1388,7 @@ async def update_chat_by_id( subject_id=id, data={'title': chat.title}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) else: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -1356,7 +1462,7 @@ async def update_chat_message_by_id( subject_id=message_id, data={'chat_id': id, 'content_preview': form_data.content[:300]}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) @router.delete('/{id}/messages/{message_id}', response_model=ChatResponse | None) @@ -1395,7 +1501,7 @@ async def delete_chat_message_by_id( subject_id=message_id, data={'chat_id': id}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) ############################ @@ -1466,64 +1572,48 @@ async def delete_chat_by_id( user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session), ): - # Cancel any in-flight LLM tasks (streaming, title/tags generation) - # before deleting the chat to prevent orphaned requests. - await stop_item_tasks(request.app.state.redis, id) - - async def delete_internal_children(owner_id: str) -> None: - child_ids = await Chats.get_internal_chat_ids_by_parent_id(id, owner_id) - for child_id in child_ids: - await stop_item_tasks(request.app.state.redis, child_id) - await Chats.delete_chat_by_id_and_user_id(child_id, owner_id) - await stop_item_tasks(request.app.state.redis, id) - + # Authorize before any side effect: cancelling a chat's in-flight tasks must + # not be reachable for a chat the caller may not delete. if user.role == 'admin': chat = await Chats.get_chat_by_id(id, db=db) - if not chat: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=ERROR_MESSAGES.NOT_FOUND, - ) - await Chats.delete_orphan_tags_for_user(chat.meta.get('tags', []), user.id, threshold=1, db=db) - await delete_internal_children(chat.user_id) - - result = await Chats.delete_chat_by_id(id, db=db) - - if result: - await publish_event( - request, - EVENTS.CHAT_DELETED, - actor=user, - subject_id=id, - data={'owner_id': chat.user_id}, - ) - return result else: if not await has_permission(user.id, 'chat.delete', await Config.get('user.permissions')): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.ACCESS_PROHIBITED, ) - chat = await Chats.get_chat_by_id_and_user_id(id, user.id, db=db) - if not chat: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=ERROR_MESSAGES.NOT_FOUND, - ) - await Chats.delete_orphan_tags_for_user(chat.meta.get('tags', []), user.id, threshold=1, db=db) - await delete_internal_children(user.id) + if not chat: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + # Cancel any in-flight LLM tasks (streaming, title/tags generation) before + # deleting the chat to prevent orphaned requests. + await stop_item_tasks(request.app.state.redis, id) + await Chats.delete_orphan_tags_for_user(chat.meta.get('tags', []), user.id, threshold=1, db=db) + + # Cascade to internal child chats spawned from this one. + for child_id in await Chats.get_internal_chat_ids_by_parent_id(id, chat.user_id): + await stop_item_tasks(request.app.state.redis, child_id) + await Chats.delete_chat_by_id_and_user_id(child_id, chat.user_id) + + if user.role == 'admin': + result = await Chats.delete_chat_by_id(id, db=db) + else: result = await Chats.delete_chat_by_id_and_user_id(id, user.id, db=db) - if result: - await publish_event( - request, - EVENTS.CHAT_DELETED, - actor=user, - subject_id=id, - data={'owner_id': user.id}, - ) - return result + + if result: + await publish_event( + request, + EVENTS.CHAT_DELETED, + actor=user, + subject_id=id, + data={'owner_id': chat.user_id}, + ) + return result ############################ @@ -1667,7 +1757,7 @@ async def fork_chat_by_id( subject_id=fork.id, data={'original_chat_id': id, 'forked_from_message_id': source_message_id}, ) - return ChatResponse(**fork.model_dump()) + return ChatResponse.model_validate(fork, from_attributes=True) @router.post('/{id}/clone', response_model=ChatResponse | None) @@ -1714,7 +1804,7 @@ async def clone_chat_by_id( subject_id=chat.id, data={'original_chat_id': id}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) else: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -1753,7 +1843,7 @@ async def clone_shared_chat_by_id( # Enforce access grants (owner and admins bypass) shared = await SharedChats.get_by_id(id, db=db) if shared and user.role != 'admin' and shared.user_id != user.id: - has_grant = await AccessGrants.has_access( + has_grant = await is_open_shared_chat(shared, db=db) or await AccessGrants.has_access( user_id=user.id, resource_type='shared_chat', resource_id=shared.chat_id, @@ -1791,7 +1881,7 @@ async def clone_shared_chat_by_id( if chats: chat = chats[0] - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) else: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -1832,7 +1922,7 @@ async def archive_chat_by_id( subject_id=id, subject_type='chat', ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) else: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT()) @@ -1866,7 +1956,7 @@ async def share_chat_by_id( subject_id=id, data={'share_id': chat.share_id, 'updated': True}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) # Create a new share shared = await SharedChats.create(id, user.id, db=db) @@ -1884,7 +1974,7 @@ async def share_chat_by_id( subject_id=id, data={'share_id': shared.id}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) # --- Delete Shared Chat --- @@ -1948,11 +2038,13 @@ async def update_shared_chat_access_by_id( user.role, form_data.access_grants, 'sharing.public_chats', + 'sharing.open_chats', + db=db, ) await AccessGrants.set_access_grants('shared_chat', id, form_data.access_grants, db=db) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) ############################ @@ -1997,6 +2089,28 @@ class ChatFolderIdForm(BaseModel): folder_id: str | None = None +@router.post('/{id}/unread') +async def mark_chat_unread_by_id( + id: str, + user=Depends(get_verified_user), + db: AsyncSession = Depends(get_async_session), +): + chat = await Chats.mark_chat_unread_by_id(id, user.id, db=db) + if not chat: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + folder_id = await Chats.get_chat_folder_id(id, user.id, db=db) + return { + 'chat_id': id, + 'last_read_at': chat.last_read_at, + 'folder_id': folder_id, + 'folder_unread_counts': await get_folder_unread_counts(user.id, db=db), + } + + @router.post('/{id}/folder', response_model=ChatResponse | None) async def update_chat_folder_id_by_id( request: Request, @@ -2027,7 +2141,7 @@ async def update_chat_folder_id_by_id( subject_id=id, data={'folder_id': form_data.folder_id}, ) - return ChatResponse(**chat.model_dump()) + return ChatResponse.model_validate(chat, from_attributes=True) else: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT()) diff --git a/backend/open_webui/routers/configs.py b/backend/open_webui/routers/configs.py index d93139396e..5235a3108c 100644 --- a/backend/open_webui/routers/configs.py +++ b/backend/open_webui/routers/configs.py @@ -205,7 +205,7 @@ async def register_oauth_client( log.debug(f'Failed to register OAuth client: {e}') raise HTTPException( status_code=400, - detail=f'Failed to register OAuth client', + detail=f'Failed to register OAuth client: {e}', ) @@ -614,7 +614,7 @@ async def verify_tool_servers_config(request: Request, form_data: ToolServerConn if form_data.headers and isinstance(form_data.headers, dict): if headers is None: headers = {} - custom_headers = get_custom_headers(form_data.headers, user) + custom_headers = await get_custom_headers(form_data.headers, user) headers.update(custom_headers) await client.connect(form_data.url, headers=headers) @@ -659,7 +659,7 @@ async def verify_tool_servers_config(request: Request, form_data: ToolServerConn if form_data.headers and isinstance(form_data.headers, dict): if headers is None: headers = {} - custom_headers = get_custom_headers(form_data.headers, user) + custom_headers = await get_custom_headers(form_data.headers, user) headers.update(custom_headers) url = get_tool_server_url(form_data.url, form_data.path) diff --git a/backend/open_webui/routers/files.py b/backend/open_webui/routers/files.py index aaebedc26c..6dcad4c421 100644 --- a/backend/open_webui/routers/files.py +++ b/backend/open_webui/routers/files.py @@ -108,6 +108,23 @@ def _cleanup_local_cache(file_path: str) -> None: log.warning(f'Failed to clean up local cache for {file_path}: {e}') +def _matches_configured_mime_type(supported: list[str] | str, content_type: str) -> bool: + if isinstance(supported, str): + supported = supported.split(',') + supported = [item.strip() for item in (supported or []) if item.strip()] + if not supported: + return False + return bool(strict_match_mime_type(supported, content_type)) + + +def _media_supported_for_extraction( + content_extraction_engine: str | None, supported: list[str] | str | None, content_type: str +) -> bool: + if supported is None: + return content_extraction_engine == 'external' + return bool(content_extraction_engine and _matches_configured_mime_type(supported, content_type)) + + async def process_uploaded_file( request, file, @@ -127,6 +144,10 @@ async def process_uploaded_file( content_type = 'text/plain' stt_supported = await Config.get('audio.stt.supported_content_types', []) + content_extraction_engine = await Config.get('rag.content_extraction_engine') + content_extraction_supported_media_mime_types = await Config.get( + 'rag.content_extraction.supported_media_mime_types' + ) if content_type and strict_match_mime_type(stt_supported, content_type): # Audio / STT-supported files → transcribe then index @@ -147,9 +168,10 @@ async def process_uploaded_file( elif ( content_type and content_type.startswith(('image/', 'video/')) - and await Config.get('rag.content_extraction_engine') != 'external' + and not _media_supported_for_extraction( + content_extraction_engine, content_extraction_supported_media_mime_types, content_type + ) ): - # Media files without an external extraction engine if content_type.startswith('video/'): # Videos are stored as-is for downstream multimodal # processing (Tools, vision models). Attempting text @@ -165,7 +187,8 @@ async def process_uploaded_file( raise Exception(f'File type {content_type} is not supported for processing') else: - # Documents, or any file when an external engine is configured + # Documents, or media files explicitly enabled for the + # configured content extraction engine. if not content_type: log.info(f'File type {file.content_type} is not provided, but trying to process anyway') await process_file( diff --git a/backend/open_webui/routers/folders.py b/backend/open_webui/routers/folders.py index 8e85eccc27..50782ea0e4 100644 --- a/backend/open_webui/routers/folders.py +++ b/backend/open_webui/routers/folders.py @@ -12,6 +12,7 @@ from open_webui.config import UPLOAD_DIR from open_webui.constants import ERROR_MESSAGES from open_webui.events import EVENTS, publish_event from open_webui.internal.db import get_async_session +from open_webui.models.chat_messages import ChatMessages from open_webui.models.config import Config from open_webui.models.chats import Chats from open_webui.models.folders import ( @@ -22,6 +23,7 @@ from open_webui.models.folders import ( FolderUpdateForm, ) from open_webui.models.access_grants import AccessGrants +from open_webui.models.automations import Automations from open_webui.models.groups import Groups from open_webui.models.users import Users from open_webui.utils.access_control import has_permission @@ -30,6 +32,7 @@ from open_webui.utils.access_control import ( ) from open_webui.utils.access_control.files import get_accessible_folder_files from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.tasks import has_active_tasks from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession @@ -42,6 +45,24 @@ router = APIRouter() from open_webui.utils.access_control.folders import has_folder_access as _has_folder_access +async def get_folder_unread_counts(user_id: str, db: AsyncSession | None = None) -> dict[str, int]: + folders = await Folders.get_folders_by_user_id(user_id, db=db) + parent_by_id = {folder.id: folder.parent_id for folder in folders} + unread_counts = dict.fromkeys(parent_by_id.keys(), 0) + direct_unread_counts = await Chats.count_unread_by_folder_ids(user_id, list(parent_by_id.keys()), db=db) + + for unread_folder_id, unread_count in direct_unread_counts.items(): + current_id = unread_folder_id + seen = set() + while current_id and current_id not in seen: + seen.add(current_id) + if current_id in unread_counts: + unread_counts[current_id] += unread_count + current_id = parent_by_id.get(current_id) + + return unread_counts + + async def check_folders_permission(request: Request, user, db=None): """Verify the folders feature is enabled and the user has permission.""" config = await Config.get_many('folders.enable', 'user.permissions') @@ -92,9 +113,14 @@ async def get_folders( folder.id, user.id, FolderUpdateForm(data=folder.data), db=db ) - folder_list.append(FolderNameIdResponse(**folder.model_dump())) + folder_list.append(folder) - return folder_list + unread_counts = await get_folder_unread_counts(user.id, db=db) + + return [ + FolderNameIdResponse(**folder.model_dump(), unread_count=unread_counts.get(folder.id, 0)) + for folder in folder_list + ] ############################ @@ -484,7 +510,7 @@ async def get_shared_folder_chats( request: Request, id: str, page: int | None = Query(None, ge=1), - sort_by: str = Query('updated_at'), + sort_by: str = Query('unread_updated_at'), sort_dir: str = Query('desc'), user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session), @@ -517,6 +543,7 @@ async def get_shared_folder_chats( limit=limit if page is not None else 60, sort_by=sort_by, sort_dir=sort_dir, + unread_for_user_id=user.id, db=db, ) total = await Chats.count_all_chats_by_folder_id(id, db=db) if page is not None else len(chats) @@ -529,6 +556,11 @@ async def get_shared_folder_chats( u = await Users.get_user_by_id(uid, db=db) owner_cache[uid] = u.name if u else 'Unknown' chat['owner_name'] = owner_cache[uid] + chat['active'] = False + if chat['user_id'] != user.id: + chat['last_read_at'] = chat['updated_at'] + if await has_active_tasks(request.app.state.redis, chat['id']): + chat['active'] = await ChatMessages.has_unfinished_assistant_by_chat_id(chat['id'], db=db) response = { 'chats': [{**chat, 'readonly': chat['user_id'] != user.id} for chat in chats], @@ -539,6 +571,44 @@ async def get_shared_folder_chats( return response +@router.post('/{id}/read') +async def mark_folder_chats_read_by_id( + request: Request, + id: str, + user=Depends(get_verified_user), + db: AsyncSession = Depends(get_async_session), +): + await check_folders_permission(request, user, db=db) + folder = await Folders.get_folder_by_id(id, db=db) + if not folder: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + is_owner = user.id == folder.user_id + is_admin = user.role == 'admin' + if not (is_owner or is_admin or await _has_folder_access(user.id, folder, 'read', db)): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + folder_ids = ( + await Folders.get_folder_ids_by_id_and_user_id_in_subtree(id, folder.user_id, db=db) + if is_owner or is_admin + else [id] + ) + updated_count = await Chats.mark_chats_read_by_folder_ids(user.id, folder_ids, db=db) + + return { + 'folder_id': id, + 'folder_ids': folder_ids, + 'updated_count': updated_count, + 'folder_unread_counts': await get_folder_unread_counts(user.id, db=db), + } + + ############################ # Delete Folder By Id ############################ @@ -556,26 +626,18 @@ async def delete_folder_by_id( folder = await Folders.get_folder_by_id_and_user_id(id, user.id, db=db) if not folder: - # Check if it's a shared subfolder with write access + # Deletion cascades into the owner's data, so only the owner or an admin may delete folder = await Folders.get_folder_by_id(id, db=db) - if folder and folder.parent_id: - if user.role != 'admin' and not await _has_folder_access(user.id, folder, 'write', db): - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail=ERROR_MESSAGES.ACCESS_PROHIBITED, - ) - elif folder and not folder.parent_id: - # Root shared folders can only be deleted by owner/admin - if user.role != 'admin': - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail=ERROR_MESSAGES.ACCESS_PROHIBITED, - ) - else: + if not folder: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND, ) + if user.role != 'admin': + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) folder_owner_id = folder.user_id @@ -607,6 +669,8 @@ async def delete_folder_by_id( # Clean up access grants for this folder await AccessGrants.revoke_all_access('folder', folder_id, db=db) + await Automations.clear_folder_ids(folder_owner_id, folder_ids, db=db) + await publish_event( request, EVENTS.FOLDER_DELETED, diff --git a/backend/open_webui/routers/functions.py b/backend/open_webui/routers/functions.py index 93d2879c18..3c1cf58cd6 100644 --- a/backend/open_webui/routers/functions.py +++ b/backend/open_webui/routers/functions.py @@ -11,7 +11,7 @@ from fastapi import APIRouter, Depends, HTTPException, Request, status from open_webui.config import CACHE_DIR from open_webui.constants import ERROR_MESSAGES from open_webui.env import AIOHTTP_CLIENT_SESSION_SSL, AIOHTTP_CLIENT_TIMEOUT, ENABLE_PLUGINS -from open_webui.events import EVENTS, publish_event +from open_webui.events import EVENTS, build_event, dispatch_event_functions, publish_event, schedule_webhook_dispatch from open_webui.internal.db import get_async_session from open_webui.models.functions import ( FunctionForm, @@ -293,6 +293,22 @@ async def toggle_function_by_id( ): function = await Functions.get_function_by_id(id, db=db) if function: + lifecycle_event = build_event( + request, + EVENTS.FUNCTION_DISABLE_STARTED if function.is_active else EVENTS.FUNCTION_ENABLE_STARTED, + actor=user, + subject_id=function.id, + subject_type='function', + data={'type': function.type, 'name': function.name}, + ) + await dispatch_event_functions( + request.app, + lifecycle_event, + request=request, + extra_function_ids=[function.id] if not function.is_active else None, + ) + schedule_webhook_dispatch(request.app, lifecycle_event) + function = await Functions.update_function_by_id(id, {'is_active': not function.is_active}, db=db) if function: diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py index b7a5772c1d..cd98681efd 100644 --- a/backend/open_webui/routers/knowledge.py +++ b/backend/open_webui/routers/knowledge.py @@ -12,7 +12,7 @@ from urllib.parse import quote from fastapi import APIRouter, Depends, HTTPException, Query, Request, status from fastapi.responses import StreamingResponse -from open_webui.config import BYPASS_ADMIN_ACCESS_CONTROL +from open_webui.config import BYPASS_ADMIN_ACCESS_CONTROL, RAG_EMBEDDING_CONTENT_PREFIX from open_webui.constants import ERROR_MESSAGES from open_webui.events import EVENTS, publish_event from open_webui.internal.db import get_async_session @@ -21,6 +21,7 @@ from open_webui.models.config import Config from open_webui.models.files import FileMetadataResponse, FileModel, FileModelResponse, Files from open_webui.models.groups import Groups from open_webui.models.knowledge import ( + KNOWLEDGE_SORTABLE_FIELDS, KnowledgeDirectoryForm, KnowledgeDirectoryModel, KnowledgeFileListResponse, @@ -73,7 +74,7 @@ async def embed_knowledge_base_metadata( """Generate and store embedding for knowledge base.""" try: content = f'{name}\n\n{description}' if description else name - embedding = await request.app.state.EMBEDDING_FUNCTION(content) + embedding = await request.app.state.EMBEDDING_FUNCTION(content, prefix=RAG_EMBEDDING_CONTENT_PREFIX) await ASYNC_VECTOR_DB_CLIENT.upsert( collection_name=KNOWLEDGE_BASES_COLLECTION, items=[ @@ -181,6 +182,8 @@ async def search_knowledge_bases( view_option: str | None = None, source: str | None = None, page: int | None = 1, + order_by: str | None = None, + direction: str | None = None, user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session), ): @@ -195,6 +198,10 @@ async def search_knowledge_bases( filter['view_option'] = view_option if source in {'local', 'external'}: filter['source'] = source + if order_by in KNOWLEDGE_SORTABLE_FIELDS: + filter['order_by'] = order_by + if direction in {'asc', 'desc'}: + filter['direction'] = direction groups = await Groups.get_groups_by_member_id(user.id, db=db) user_group_ids = {group.id for group in groups} @@ -1936,6 +1943,10 @@ async def sync_knowledge_cleanup( if not file: continue + # Only clean up files that belong to this knowledge base. + if not await Knowledges.has_file(id, file_id, db=db): + continue + await Knowledges.remove_file_from_knowledge_by_id(id, file_id, db=db) try: @@ -1960,6 +1971,10 @@ async def sync_knowledge_cleanup( # ── Remove orphaned directories (children before parents) ── for dir_id in reversed(form_data.dir_ids): + # Only delete directories that belong to this knowledge base. + directory = await Knowledges.get_directory_by_id(dir_id, db=db) + if not directory or directory.knowledge_id != id: + continue await Knowledges.delete_directory(dir_id, move_files_to_parent=False, db=db) return {'status': True} diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py index 8e6d50f39a..26c8293d88 100644 --- a/backend/open_webui/routers/memories.py +++ b/backend/open_webui/routers/memories.py @@ -5,13 +5,13 @@ import logging from typing import Literal from fastapi import APIRouter, Depends, HTTPException, Request, status +from open_webui.config import RAG_EMBEDDING_CONTENT_PREFIX, RAG_EMBEDDING_QUERY_PREFIX from open_webui.constants import ERROR_MESSAGES from open_webui.events import EVENTS, publish_event from open_webui.internal.db import get_async_session from open_webui.models.config import Config from open_webui.models.memories import Memories, MemoryModel from open_webui.retrieval.vector.async_client import ASYNC_VECTOR_DB_CLIENT -from open_webui.config import RAG_EMBEDDING_QUERY_PREFIX from open_webui.utils.access_control import has_permission from open_webui.utils.auth import get_verified_user from open_webui.utils.memory import ( @@ -148,7 +148,9 @@ async def add_memory( meta={'created_by': 'manual'}, ) - vector = await request.app.state.EMBEDDING_FUNCTION(memory_vector_text(memory.content, memory.path), user=user) + vector = await request.app.state.EMBEDDING_FUNCTION( + memory_vector_text(memory.content, memory.path), prefix=RAG_EMBEDDING_CONTENT_PREFIX, user=user + ) await ASYNC_VECTOR_DB_CLIENT.upsert( collection_name=f'user-memory-{user.id}', @@ -208,6 +210,7 @@ async def update_memories( if result.get('status') in {'created', 'updated'}: vector = await request.app.state.EMBEDDING_FUNCTION( memory_vector_text(memory.content, memory.path), + prefix=RAG_EMBEDDING_CONTENT_PREFIX, user=user, ) upsert_items.append( @@ -284,7 +287,7 @@ async def query_memory( if not memories: raise HTTPException(status_code=404, detail='No memories found for user') - vector = await request.app.state.EMBEDDING_FUNCTION(form_data.content, RAG_EMBEDDING_QUERY_PREFIX, user=user) + vector = await request.app.state.EMBEDDING_FUNCTION(form_data.content, prefix=RAG_EMBEDDING_QUERY_PREFIX, user=user) results = await ASYNC_VECTOR_DB_CLIENT.search( collection_name=f'user-memory-{user.id}', @@ -407,7 +410,9 @@ async def reset_memory_from_vector_db( # Generate vectors in parallel vectors = await asyncio.gather( *[ - request.app.state.EMBEDDING_FUNCTION(memory_vector_text(memory.content, memory.path), user=user) + request.app.state.EMBEDDING_FUNCTION( + memory_vector_text(memory.content, memory.path), prefix=RAG_EMBEDDING_CONTENT_PREFIX, user=user + ) for memory in memories ] ) @@ -503,7 +508,9 @@ async def update_memory_by_id( raise HTTPException(status_code=404, detail=ERROR_MESSAGES.NOT_FOUND) if form_data.content is not None or form_data.path is not None: - vector = await request.app.state.EMBEDDING_FUNCTION(memory_vector_text(memory.content, memory.path), user=user) + vector = await request.app.state.EMBEDDING_FUNCTION( + memory_vector_text(memory.content, memory.path), prefix=RAG_EMBEDDING_CONTENT_PREFIX, user=user + ) await ASYNC_VECTOR_DB_CLIENT.upsert( collection_name=f'user-memory-{user.id}', diff --git a/backend/open_webui/routers/models.py b/backend/open_webui/routers/models.py index 8af1afbdce..e2137d6654 100644 --- a/backend/open_webui/routers/models.py +++ b/backend/open_webui/routers/models.py @@ -50,7 +50,7 @@ router = APIRouter() def add_chat_variables_schema(model_dict: dict) -> dict: - system = ((model_dict.get('params') or {}).get('system') if isinstance(model_dict.get('params'), dict) else None) + system = (model_dict.get('params') or {}).get('system') if isinstance(model_dict.get('params'), dict) else None schema = get_chat_variables_schema(system) if schema: model_dict.setdefault('meta', {})['chat_variables_schema'] = schema @@ -189,16 +189,16 @@ async def get_models( data = add_chat_variables_schema(model.model_dump()) if data.get('meta'): data['meta'].pop('profile_image_url', None) - items.append( - ModelAccessResponse( - **data, - write_access=( - (user.role == 'admin' and BYPASS_ADMIN_ACCESS_CONTROL) - or user.id == model.user_id - or model.id in writable_model_ids - ), - ) + write_access = ( + (user.role == 'admin' and BYPASS_ADMIN_ACCESS_CONTROL) + or user.id == model.user_id + or model.id in writable_model_ids ) + # Strip params (system prompt and other curated config) for read-only + # callers, mirroring the per-id endpoint. + if not write_access: + data['params'] = {} + items.append(ModelAccessResponse(**data, write_access=write_access)) return ModelAccessListResponse( items=items, diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index ff1bc3a19a..b91aed2ac4 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -24,7 +24,6 @@ from open_webui.constants import ERROR_MESSAGES from open_webui.events import EVENTS, publish_event, publish_model_provider_request_failed from open_webui.env import ( AIOHTTP_CLIENT_SESSION_SSL, - AIOHTTP_CLIENT_TIMEOUT, AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST, AIOHTTP_FILE_STREAM_CHUNK_SIZE, BYPASS_MODEL_ACCESS_CONTROL, @@ -41,13 +40,15 @@ from open_webui.models.users import UserModel from open_webui.utils.access_control import check_model_access from open_webui.utils.auth import get_admin_user, get_verified_user from open_webui.utils.headers import get_custom_headers, include_user_info_headers +from open_webui.utils.model_ids import strip_provider_model_prefix +from open_webui.utils.json_codec import JSONCodec from open_webui.utils.misc import calculate_sha256 from open_webui.utils.payload import ( apply_model_params_to_body_ollama, apply_model_params_to_body_openai, apply_system_prompt_to_body, ) -from open_webui.utils.session_pool import cleanup_response, get_session, stream_wrapper +from open_webui.utils.session_pool import cleanup_response, get_client_timeout, get_session, stream_wrapper log = logging.getLogger(__name__) @@ -56,6 +57,7 @@ log = logging.getLogger(__name__) # clients to attempt decompression of an already-decoded payload, resulting # in ZlibError. See https://github.com/aio-libs/aiohttp/issues/4462. _STRIP_PROXY_HEADERS = frozenset({'Content-Encoding', 'Content-Length', 'Transfer-Encoding'}) +_MODEL_LIST_TIMEOUT = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST) def _clean_proxy_headers(raw_headers) -> dict: @@ -83,9 +85,9 @@ async def send_get_request( url, headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST), + timeout=_MODEL_LIST_TIMEOUT, ) as r: - return await r.json() + return await r.json(loads=JSONCodec.loads) except Exception as exc: log.error(f'Connection error: {exc}') return None @@ -99,6 +101,8 @@ async def send_request( key: str | None = None, user: UserModel = None, stream: bool = False, + # passthrough must stay False for /api/chat: middleware parses it per line + passthrough: bool = False, content_type: str | None = None, metadata: dict | None = None, api_config: dict | None = None, @@ -121,7 +125,7 @@ async def send_request( # Custom per-connection headers last so admin-set headers take precedence. if api_config and api_config.get('headers'): - headers.update(get_custom_headers(api_config['headers'], user, metadata, request=request)) + headers.update(await get_custom_headers(api_config['headers'], user, metadata, request=request)) r = await session.request( method, @@ -129,12 +133,12 @@ async def send_request( data=payload, headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(stream=stream), ) if not r.ok: try: - res = await r.json() + res = await r.json(loads=JSONCodec.loads) await publish_model_provider_request_failed( request, actor=user, @@ -170,13 +174,13 @@ async def send_request( streaming = True return StreamingResponse( - stream_wrapper(r), + stream_wrapper(r, passthrough=passthrough), status_code=r.status, headers=response_headers, ) else: try: - return await r.json() + return await r.json(loads=JSONCodec.loads) except Exception: return None @@ -263,16 +267,16 @@ async def verify_connection( f'{form_data.url}/api/version', headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST), + timeout=_MODEL_LIST_TIMEOUT, ) as r: if r.status != 200: detail = f'HTTP Error: {r.status}' - res = await r.json() + res = await r.json(loads=JSONCodec.loads) if 'error' in res: detail = f'External Error: {res["error"]}' raise Exception(detail) - return await r.json() + return await r.json(loads=JSONCodec.loads) except aiohttp.ClientError as exc: log.exception(f'Client error: {exc}') raise HTTPException(status_code=500, detail=ERROR_MESSAGES.SERVER_CONNECTION_ERROR) @@ -535,6 +539,7 @@ async def get_ollama_loaded_models( @router.get('/api/version/{url_idx}') async def get_ollama_versions( request: Request, + user=Depends(get_verified_user), url_idx: int | None = None, ): """Return the lowest Ollama version across all configured backends.""" @@ -656,6 +661,7 @@ async def pull_model( key=get_api_key(url_idx, url, (await Config.get('ollama.api_configs', {}))), user=user, stream=True, + passthrough=True, ) @@ -695,6 +701,7 @@ async def push_model( key=get_api_key(url_idx, url, (await Config.get('ollama.api_configs', {}))), user=user, stream=True, + passthrough=True, ) @@ -727,6 +734,7 @@ async def create_model( key=get_api_key(url_idx, url, (await Config.get('ollama.api_configs', {}))), user=user, stream=True, + passthrough=True, ) @@ -895,8 +903,7 @@ async def embed( key = get_api_key(url_idx, url, api_configs) prefix_id = api_config.get('prefix_id') - if prefix_id: - form_data.model = form_data.model.replace(f'{prefix_id}.', '') + form_data.model = strip_provider_model_prefix(form_data.model, prefix_id) return await send_request( f'{url}/api/embed', @@ -947,8 +954,7 @@ async def embeddings( key = get_api_key(url_idx, url, api_configs) prefix_id = api_config.get('prefix_id') - if prefix_id: - form_data.model = form_data.model.replace(f'{prefix_id}.', '') + form_data.model = strip_provider_model_prefix(form_data.model, prefix_id) return await send_request( f'{url}/api/embeddings', @@ -1003,8 +1009,7 @@ async def generate_completion( api_config = api_configs.get(str(url_idx), api_configs.get(url, {})) prefix_id = api_config.get('prefix_id') - if prefix_id: - form_data.model = form_data.model.replace(f'{prefix_id}.', '') + form_data.model = strip_provider_model_prefix(form_data.model, prefix_id) return await send_request( f'{url}/api/generate', @@ -1012,6 +1017,7 @@ async def generate_completion( key=get_api_key(url_idx, url, api_configs), user=user, stream=True, + passthrough=True, ) @@ -1063,6 +1069,10 @@ async def get_ollama_url(request: Request, model: str, url_idx: int | None = Non await validate_ollama_backend_idx(request, model, url_idx, user) if url_idx is None: models = request.app.state.OLLAMA_MODELS + if not models or model not in models: + await get_all_models.cache.clear() + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS if model not in models: raise HTTPException( status_code=400, @@ -1107,7 +1117,7 @@ async def generate_chat_completion( raise HTTPException(status_code=400, detail=str(exc)) if isinstance(form_data, BaseModel): - payload = {**form_data.model_dump(exclude_none=True)} + payload = form_data.model_dump(exclude_none=True) payload.pop('metadata', None) @@ -1135,8 +1145,7 @@ async def generate_chat_completion( api_config = resolve_api_config(api_configs, url_idx, url) prefix_id = api_config.get('prefix_id') - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) return await send_request( f'{url}/api/chat', @@ -1212,8 +1221,7 @@ async def generate_openai_completion( log.exception(exc) raise HTTPException(status_code=400, detail=str(exc)) - payload = {**form_data.model_dump(exclude_none=True, exclude=['metadata'])} - payload.pop('metadata', None) + payload = form_data.model_dump(exclude_none=True, exclude=['metadata']) model_id = form_data.model model_info = await Models.get_model_by_id(model_id) @@ -1232,8 +1240,7 @@ async def generate_openai_completion( api_config = resolve_api_config(api_configs, url_idx, url) prefix_id = api_config.get('prefix_id') - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) return await send_request( f'{url}/v1/completions', @@ -1241,6 +1248,7 @@ async def generate_openai_completion( key=get_api_key(url_idx, url, api_configs), user=user, stream=payload.get('stream', False), + passthrough=True, metadata=metadata, api_config=api_config, request=request, @@ -1267,7 +1275,7 @@ async def generate_openai_embeddings( log.exception(exc) raise HTTPException(status_code=400, detail=str(exc)) - payload = {**form_data.model_dump(exclude_none=True)} + payload = form_data.model_dump(exclude_none=True) payload.pop('metadata', None) model_id = form_data.model @@ -1283,8 +1291,7 @@ async def generate_openai_embeddings( api_config = resolve_api_config((await Config.get('ollama.api_configs', {})), url_idx, url) prefix_id = api_config.get('prefix_id') - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) return await send_request( f'{url}/v1/embeddings', @@ -1318,8 +1325,7 @@ async def generate_openai_chat_completion( log.exception(exc) raise HTTPException(status_code=400, detail=str(exc)) - payload = {**form_data.model_dump(exclude_none=True, exclude=['metadata'])} - payload.pop('metadata', None) + payload = form_data.model_dump(exclude_none=True, exclude=['metadata']) model_id = form_data.model model_info = await Models.get_model_by_id(model_id) @@ -1342,8 +1348,7 @@ async def generate_openai_chat_completion( api_config = resolve_api_config(api_configs, url_idx, url) prefix_id = api_config.get('prefix_id') - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) return await send_request( f'{url}/v1/chat/completions', @@ -1351,6 +1356,7 @@ async def generate_openai_chat_completion( key=get_api_key(url_idx, url, api_configs), user=user, stream=payload.get('stream', False), + passthrough=True, metadata=metadata, api_config=api_config, request=request, @@ -1394,8 +1400,7 @@ async def generate_anthropic_messages( api_config = api_configs.get(str(url_idx), api_configs.get(url, {})) # Legacy support prefix_id = api_config.get('prefix_id', None) - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) return await send_request( f'{url}/v1/messages', @@ -1403,6 +1408,7 @@ async def generate_anthropic_messages( key=get_api_key(url_idx, url, api_configs), user=user, stream=payload.get('stream', False), + passthrough=True, content_type='text/event-stream' if payload.get('stream', False) else None, api_config=api_config, request=request, @@ -1452,8 +1458,7 @@ async def generate_responses( api_config = api_configs.get(str(url_idx), api_configs.get(url, {})) # Legacy support prefix_id = api_config.get('prefix_id', None) - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) return await send_request( f'{url}/v1/responses', @@ -1461,6 +1466,7 @@ async def generate_responses( key=get_api_key(url_idx, url, api_configs), user=user, stream=payload.get('stream', False), + passthrough=True, content_type='text/event-stream' if payload.get('stream', False) else None, api_config=api_config, request=request, @@ -1661,7 +1667,7 @@ async def upload_model( data=blob_chunks(), headers={'Content-Length': str(total_size)}, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(), ) as resp: if not resp.ok: raise Exception('Ollama: Could not create blob, Please try again.') @@ -1684,7 +1690,7 @@ async def upload_model( headers={'Content-Type': 'application/json'}, data=json.dumps(create_payload), ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(), ) as create_resp: if create_resp.ok: log.info('API SUCCESS!') diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py index 5d0f9062ed..d5cad77bef 100644 --- a/backend/open_webui/routers/openai.py +++ b/backend/open_webui/routers/openai.py @@ -26,7 +26,6 @@ from open_webui.constants import ERROR_MESSAGES from open_webui.events import EVENTS, publish_event, publish_model_provider_request_failed from open_webui.env import ( AIOHTTP_CLIENT_SESSION_SSL, - AIOHTTP_CLIENT_TIMEOUT, AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST, BYPASS_MODEL_ACCESS_CONTROL, ENABLE_FORWARD_USER_INFO_HEADERS, @@ -44,6 +43,8 @@ from open_webui.utils.access_control import check_model_access, has_connection_a from open_webui.utils.anthropic import get_anthropic_models, is_anthropic_url from open_webui.utils.auth import get_admin_user, get_verified_user from open_webui.utils.headers import get_custom_headers, include_user_info_headers +from open_webui.utils.json_codec import JSONCodec +from open_webui.utils.model_ids import strip_provider_model_prefix from open_webui.utils.misc import ( convert_logit_bias_input_to_json, stream_chunks_handler, @@ -54,6 +55,7 @@ from open_webui.utils.payload import ( ) from open_webui.utils.session_pool import ( cleanup_response, + get_client_timeout, get_session, stream_wrapper, ) @@ -76,6 +78,8 @@ log = logging.getLogger(__name__) # clients to attempt decompression of an already-decoded payload, resulting # in ZlibError. See https://github.com/aio-libs/aiohttp/issues/4462. _STRIP_PROXY_HEADERS = frozenset({'Content-Encoding', 'Content-Length', 'Transfer-Encoding'}) +_MODEL_LIST_TIMEOUT = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST) +_UNSUPPORTED_OPENAI_MODEL_KEYWORDS = ('babbage', 'dall-e', 'davinci', 'embedding', 'tts', 'whisper') def _clean_proxy_headers(raw_headers) -> dict: @@ -90,9 +94,8 @@ async def send_get_request( user: UserModel = None, config=None, ): - timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST) try: - async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: + async with aiohttp.ClientSession(timeout=_MODEL_LIST_TIMEOUT, trust_env=True) as session: if request and config: headers, cookies = await get_headers_and_cookies(request, url, key, config, user=user) else: @@ -110,7 +113,7 @@ async def send_get_request( cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_SSL, ) as response: - return await response.json() + return await response.json(loads=JSONCodec.loads) except Exception as e: # Handle connection error here log.error(f'Connection error: {e}') @@ -210,7 +213,7 @@ async def get_headers_and_cookies( headers['Authorization'] = f'Bearer {token}' if config.get('headers') and isinstance(config.get('headers'), dict): - custom_headers = get_custom_headers(config.get('headers'), user, metadata, request=request) + custom_headers = await get_custom_headers(config.get('headers'), user, metadata, request=request) headers.update(custom_headers) return headers, cookies @@ -328,8 +331,7 @@ async def get_anthropic_token_count_target(request: Request, form_data: dict, us url, key, api_config = await get_openai_connection(model['urlIdx']) prefix_id = api_config.get('prefix_id') - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) headers, cookies = await get_headers_and_cookies(request, url, key, api_config, user=user) return requested_model, payload, url, key, headers, cookies @@ -352,11 +354,11 @@ async def count_anthropic_tokens(request: Request, form_data: dict, user: UserMo headers=headers, cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(), ) try: - response_data = await response.json() + response_data = await response.json(loads=JSONCodec.loads) except Exception: response_data = await response.text() @@ -508,7 +510,7 @@ async def speech(request: Request, user=Depends(get_verified_user)): detail = None if r is not None: try: - res = await r.json() + res = await r.json(loads=JSONCodec.loads) if 'error' in res: detail = f'External: {res["error"]}' except Exception: @@ -659,19 +661,7 @@ async def get_all_models(request: Request, user: UserModel) -> dict[str, list]: return None def is_supported_openai_models(model_id): - if any( - name in model_id - for name in [ - 'babbage', - 'dall-e', - 'davinci', - 'embedding', - 'tts', - 'whisper', - ] - ): - return False - return True + return not any(name in model_id for name in _UNSUPPORTED_OPENAI_MODEL_KEYWORDS) def get_merged_models(model_lists): log.debug(f'merge_models_lists {model_lists}') @@ -679,17 +669,18 @@ async def get_all_models(request: Request, user: UserModel) -> dict[str, list]: for idx, model_list in enumerate(model_lists): if model_list is not None and 'error' not in model_list: + base_url = api_base_urls[idx] + hostname = urlparse(base_url).hostname if base_url else None + api_config = api_configs.get(str(idx), api_configs.get(base_url, {})) + for model in model_list: model_id = model.get('id') or model.get('name') - base_url = api_base_urls[idx] - hostname = urlparse(base_url).hostname if base_url else None if hostname == 'api.openai.com' and not is_supported_openai_models(model_id): # Skip unwanted OpenAI models continue if model_id and model_id not in models: - api_config = api_configs.get(str(idx), api_configs.get(base_url, {})) provider = model.get('provider', '') merged = { **model, @@ -738,7 +729,7 @@ async def get_models(request: Request, url_idx: int | None = None, user=Depends( r = None async with aiohttp.ClientSession( trust_env=True, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST), + timeout=_MODEL_LIST_TIMEOUT, ) as session: try: headers, cookies = await get_headers_and_cookies(request, url, key, api_config, user=user) @@ -762,30 +753,20 @@ async def get_models(request: Request, url_idx: int | None = None, user=Depends( if r.status != 200: error_detail = f'HTTP Error: {r.status}' try: - res = await r.json() + res = await r.json(loads=JSONCodec.loads) if 'error' in res: error_detail = f'External Error: {res["error"]}' except Exception: pass raise Exception(error_detail) - response_data = await r.json() + response_data = await r.json(loads=JSONCodec.loads) if 'api.openai.com' in url: response_data['data'] = [ model for model in response_data.get('data', []) - if not any( - name in model['id'] - for name in [ - 'babbage', - 'dall-e', - 'davinci', - 'embedding', - 'tts', - 'whisper', - ] - ) + if not any(name in model['id'] for name in _UNSUPPORTED_OPENAI_MODEL_KEYWORDS) ] models = response_data @@ -824,7 +805,7 @@ async def verify_connection( async with aiohttp.ClientSession( trust_env=True, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST), + timeout=_MODEL_LIST_TIMEOUT, ) as session: try: headers, cookies = await get_headers_and_cookies(request, url, key, api_config, user=user) @@ -852,7 +833,7 @@ async def verify_connection( ssl=AIOHTTP_CLIENT_SESSION_SSL, ) as r: try: - response_data = await r.json() + response_data = await r.json(loads=JSONCodec.loads) except Exception: response_data = await r.text() @@ -878,7 +859,7 @@ async def verify_connection( ssl=AIOHTTP_CLIENT_SESSION_SSL, ) as r: try: - response_data = await r.json() + response_data = await r.json(loads=JSONCodec.loads) except Exception: response_data = await r.text() @@ -1268,8 +1249,7 @@ async def generate_chat_completion( url, key, api_config = await get_openai_connection(idx) prefix_id = api_config.get('prefix_id', None) - if prefix_id: - payload['model'] = payload['model'].replace(f'{prefix_id}.', '') + payload['model'] = strip_provider_model_prefix(payload['model'], prefix_id) # Add user info to the payload if the model is a pipeline if 'pipeline' in model and model.get('pipeline'): @@ -1345,6 +1325,10 @@ async def generate_chat_completion( part.get('text', '') for part in message['content'] if part.get('type') in ('input_text', 'text') ) + is_streaming_request = bool(payload.get('stream', False)) + if not is_streaming_request: + payload.pop('stream_options', None) + payload = json.dumps(payload) r = None @@ -1361,7 +1345,7 @@ async def generate_chat_completion( headers=headers, cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(stream=is_streaming_request), ) # Check if response is SSE @@ -1413,7 +1397,7 @@ async def generate_chat_completion( ) else: try: - response = await r.json() + response = await r.json(loads=JSONCodec.loads) except Exception as e: log.error(e) response = await r.text() @@ -1512,20 +1496,20 @@ async def embeddings(request: Request, form_data: dict, user): data=body, headers=headers, cookies=cookies, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(), ssl=AIOHTTP_CLIENT_SESSION_SSL, ) if 'text/event-stream' in r.headers.get('Content-Type', ''): streaming = True return StreamingResponse( - stream_wrapper(r), + stream_wrapper(r, passthrough=True), status_code=r.status, headers=_clean_proxy_headers(r.headers), ) else: try: - response_data = await r.json() + response_data = await r.json(loads=JSONCodec.loads) except Exception: response_data = await r.text() @@ -1588,6 +1572,7 @@ async def responses( Routes to the correct upstream backend based on the model field. """ payload = form_data.model_dump(exclude_none=True) + is_streaming_request = bool(payload.get('stream', False)) idx = 0 model_id = form_data.model @@ -1638,20 +1623,20 @@ async def responses( headers=headers, cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(stream=is_streaming_request), ) # Check if response is SSE if 'text/event-stream' in r.headers.get('Content-Type', ''): streaming = True return StreamingResponse( - stream_wrapper(r), + stream_wrapper(r, passthrough=True), status_code=r.status, headers=_clean_proxy_headers(r.headers), ) else: try: - response_data = await r.json() + response_data = await r.json(loads=JSONCodec.loads) except Exception: response_data = await r.text() @@ -1708,6 +1693,7 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)): payload = json.loads(body) except (json.JSONDecodeError, ValueError): payload = None + is_streaming_request = bool(payload.get('stream', False)) if isinstance(payload, dict) else False idx = 0 model_id = payload.get('model') if isinstance(payload, dict) else None @@ -1759,20 +1745,20 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)): headers=headers, cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_SSL, - timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + timeout=get_client_timeout(stream=is_streaming_request), ) # Check if response is SSE if 'text/event-stream' in r.headers.get('Content-Type', ''): streaming = True return StreamingResponse( - stream_wrapper(r), + stream_wrapper(r, passthrough=True), status_code=r.status, headers=_clean_proxy_headers(r.headers), ) else: try: - response_data = await r.json() + response_data = await r.json(loads=JSONCodec.loads) except Exception: response_data = await r.text() diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index 9116dc80de..4bb2fbca88 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -101,6 +101,7 @@ from open_webui.retrieval.web.ollama import search_ollama_cloud from open_webui.retrieval.web.perplexity import search_perplexity from open_webui.retrieval.web.perplexity_search import search_perplexity_search from open_webui.retrieval.web.searchapi import search_searchapi +from open_webui.retrieval.web.openserp import search_openserp from open_webui.retrieval.web.searxng import search_searxng from open_webui.retrieval.web.serpapi import search_serpapi from open_webui.retrieval.web.serper import search_serper @@ -264,6 +265,7 @@ RETRIEVAL_CONFIG_KEYS = { 'CHUNK_MIN_SIZE_TARGET': 'rag.chunk_min_size_target', 'CHUNK_OVERLAP': 'rag.chunk_overlap', 'CHUNK_SIZE': 'rag.chunk_size', + 'CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES': 'rag.content_extraction.supported_media_mime_types', 'CONTENT_EXTRACTION_ENGINE': 'rag.content_extraction_engine', 'DATALAB_MARKER_ADDITIONAL_CONFIG': 'rag.datalab_marker_additional_config', 'DATALAB_MARKER_API_BASE_URL': 'rag.datalab_marker_api_base_url', @@ -365,6 +367,7 @@ RETRIEVAL_CONFIG_KEYS = { 'SEARCHAPI_ENGINE': 'web.search.searchapi_engine', 'SEARXNG_LANGUAGE': 'web.search.searxng_language', 'SEARXNG_QUERY_URL': 'web.search.searxng_query_url', + 'OPENSERP_BASE_URL': 'web.search.openserp_base_url', 'SERPAPI_API_KEY': 'web.search.serpapi_api_key', 'SERPAPI_ENGINE': 'web.search.serpapi_engine', 'SERPER_API_KEY': 'web.search.serper_api_key', @@ -628,6 +631,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)): 'HYBRID_BM25_WEIGHT': config.HYBRID_BM25_WEIGHT, # Content extraction settings 'CONTENT_EXTRACTION_ENGINE': config.CONTENT_EXTRACTION_ENGINE, + 'CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES': config.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES, 'PDF_EXTRACT_IMAGES': config.PDF_EXTRACT_IMAGES, 'PDF_LOADER_MODE': config.PDF_LOADER_MODE, 'DATALAB_MARKER_API_KEY': config.DATALAB_MARKER_API_KEY, @@ -703,6 +707,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)): 'OLLAMA_CLOUD_WEB_SEARCH_API_KEY': config.OLLAMA_CLOUD_WEB_SEARCH_API_KEY, 'SEARXNG_QUERY_URL': config.SEARXNG_QUERY_URL, 'SEARXNG_LANGUAGE': config.SEARXNG_LANGUAGE, + 'OPENSERP_BASE_URL': config.OPENSERP_BASE_URL, 'YACY_QUERY_URL': config.YACY_QUERY_URL, 'YACY_USERNAME': config.YACY_USERNAME, 'YACY_PASSWORD': config.YACY_PASSWORD, @@ -781,6 +786,7 @@ class WebConfig(BaseModel): OLLAMA_CLOUD_WEB_SEARCH_API_KEY: str | None = None SEARXNG_QUERY_URL: str | None = None SEARXNG_LANGUAGE: str | None = None + OPENSERP_BASE_URL: str | None = None YACY_QUERY_URL: str | None = None YACY_USERNAME: str | None = None YACY_PASSWORD: str | None = None @@ -857,6 +863,7 @@ class ConfigForm(BaseModel): # Content extraction settings CONTENT_EXTRACTION_ENGINE: str | None = None + CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES: list[str] | None = None PDF_EXTRACT_IMAGES: bool | None = None PDF_LOADER_MODE: str | None = None @@ -969,6 +976,11 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend if form_data.CONTENT_EXTRACTION_ENGINE is not None else config.CONTENT_EXTRACTION_ENGINE ) + config.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES = ( + form_data.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES + if form_data.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES is not None + else config.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES + ) config.PDF_EXTRACT_IMAGES = ( form_data.PDF_EXTRACT_IMAGES if form_data.PDF_EXTRACT_IMAGES is not None else config.PDF_EXTRACT_IMAGES ) @@ -1249,6 +1261,7 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend config.OLLAMA_CLOUD_WEB_SEARCH_API_KEY = form_data.web.OLLAMA_CLOUD_WEB_SEARCH_API_KEY config.SEARXNG_QUERY_URL = form_data.web.SEARXNG_QUERY_URL config.SEARXNG_LANGUAGE = form_data.web.SEARXNG_LANGUAGE + config.OPENSERP_BASE_URL = form_data.web.OPENSERP_BASE_URL config.YACY_QUERY_URL = form_data.web.YACY_QUERY_URL config.YACY_USERNAME = form_data.web.YACY_USERNAME config.YACY_PASSWORD = form_data.web.YACY_PASSWORD @@ -1328,6 +1341,7 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend 'HYBRID_BM25_WEIGHT': config.HYBRID_BM25_WEIGHT, # Content extraction settings 'CONTENT_EXTRACTION_ENGINE': config.CONTENT_EXTRACTION_ENGINE, + 'CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES': config.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES, 'PDF_EXTRACT_IMAGES': config.PDF_EXTRACT_IMAGES, 'PDF_LOADER_MODE': config.PDF_LOADER_MODE, 'DATALAB_MARKER_API_KEY': config.DATALAB_MARKER_API_KEY, @@ -1400,6 +1414,7 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend 'OLLAMA_CLOUD_WEB_SEARCH_API_KEY': config.OLLAMA_CLOUD_WEB_SEARCH_API_KEY, 'SEARXNG_QUERY_URL': config.SEARXNG_QUERY_URL, 'SEARXNG_LANGUAGE': config.SEARXNG_LANGUAGE, + 'OPENSERP_BASE_URL': config.OPENSERP_BASE_URL, 'YACY_QUERY_URL': config.YACY_QUERY_URL, 'YACY_USERNAME': config.YACY_USERNAME, 'YACY_PASSWORD': config.YACY_PASSWORD, @@ -1564,12 +1579,21 @@ def get_transformers_tokenizer(request: Request, config: RetrievalConfig): if not os.path.exists(tokenizer_model) and '/' not in tokenizer_model: tokenizer_model = f'sentence-transformers/{tokenizer_model}' - return AutoTokenizer.from_pretrained( + cache_dir = os.getenv('SENTENCE_TRANSFORMERS_HOME') or os.getenv('HF_HUB_CACHE') + local_files_only = not RAG_EMBEDDING_MODEL_AUTO_UPDATE + tokenizer_key = (tokenizer_model, cache_dir, local_files_only) + cached_tokenizer = getattr(request.app.state, 'transformers_tokenizer', None) + if cached_tokenizer and cached_tokenizer[0] == tokenizer_key: + return cached_tokenizer[1] + + tokenizer = AutoTokenizer.from_pretrained( tokenizer_model, - cache_dir=os.getenv('SENTENCE_TRANSFORMERS_HOME') or os.getenv('HF_HUB_CACHE'), + cache_dir=cache_dir, trust_remote_code=RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE, - local_files_only=not RAG_EMBEDDING_MODEL_AUTO_UPDATE, + local_files_only=local_files_only, ) + request.app.state.transformers_tokenizer = (tokenizer_key, tokenizer) + return tokenizer tokenizer = getattr(getattr(request.app.state, 'ef', None), 'tokenizer', None) if tokenizer is not None: @@ -1937,7 +1961,7 @@ async def process_file( ] text_content = ' '.join([doc.page_content for doc in docs]) - log.debug(f'text_content: {text_content}') + log.debug('text_content: %s', text_content) await Files.update_file_data_by_id( file.id, {'content': text_content}, @@ -2079,7 +2103,7 @@ async def process_text( ) ] text_content = form_data.content - log.debug(f'text_content: {text_content}') + log.debug('text_content: %s', text_content) config = await get_retrieval_config() result = await run_in_threadpool(save_docs_to_vector_db, request, docs, collection_name, config, user=user) @@ -2116,7 +2140,7 @@ async def process_web( config = await get_retrieval_config() try: content, docs = await get_content_from_url(request, form_data.url) - log.debug(f'text_content: {content}') + log.debug('text_content: %s', content) if process: collection_name = form_data.collection_name @@ -2212,6 +2236,16 @@ async def search_web(request: Request, engine: str, query: str, user=None) -> li ) else: raise Exception('No SEARXNG_QUERY_URL found in environment variables') + elif engine == 'openserp': + if config.OPENSERP_BASE_URL: + return await search_openserp( + config.OPENSERP_BASE_URL, + query, + config.WEB_SEARCH_RESULT_COUNT, + config.WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception('No OPENSERP_BASE_URL found in environment variables') elif engine == 'yacy': if config.YACY_QUERY_URL: return await asyncio.to_thread( @@ -2607,20 +2641,22 @@ async def process_web_search(request: Request, form_data: SearchForm, user=Depen if hasattr(result, 'snippet') and result.snippet is not None ] else: + loader_config = await get_loader_config() loader = get_web_loader( urls, - verify_ssl=config.ENABLE_WEB_LOADER_SSL_VERIFICATION, - requests_per_second=config.WEB_LOADER_CONCURRENT_REQUESTS, - trust_env=config.WEB_SEARCH_TRUST_ENV, - loader_config=await get_loader_config(), + verify_ssl=loader_config.get('web_loader_ssl_verification'), + requests_per_second=loader_config.get('web_loader_concurrent_requests'), + trust_env=loader_config.get('web_search_trust_env'), + loader_config=loader_config, ) docs = await loader.aload() urls = [ doc.metadata.get('source') for doc in docs if doc.metadata.get('source') ] # only keep the urls returned by the loader + url_set = set(urls) result_items = [ - dict(item) for item in result_items if item.link in urls + dict(item) for item in result_items if item.link in url_set ] # only keep the search results that have been loaded if config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL: @@ -2640,7 +2676,8 @@ async def process_web_search(request: Request, form_data: SearchForm, user=Depen } else: # Create a single collection for all documents - collection_name = f'web-search-{calculate_sha256_string("-".join(form_data.queries))}'[:63] + # Bind the ephemeral collection to its owner so filter_accessible_collections can scope it per-user. + collection_name = f'web-search-{user.id}-{calculate_sha256_string("-".join(form_data.queries))}'[:63] try: await run_in_threadpool( @@ -2653,7 +2690,12 @@ async def process_web_search(request: Request, form_data: SearchForm, user=Depen user=user, ) except Exception as e: - log.debug(f'error saving docs: {e}') + # Surface the failure instead of returning an unusable collection + log.exception(f'Error saving web search results to vector DB: {e}') + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, + detail='Failed to embed and store the retrieved web pages. Check the embedding configuration in Admin Settings > Documents.', + ) return { 'status': True, diff --git a/backend/open_webui/routers/terminals.py b/backend/open_webui/routers/terminals.py index 1d89b4754c..b2f997cb38 100644 --- a/backend/open_webui/routers/terminals.py +++ b/backend/open_webui/routers/terminals.py @@ -17,7 +17,6 @@ from open_webui.events import EVENTS, publish_event from open_webui.env import AIOHTTP_CLIENT_SESSION_SSL from open_webui.models.config import Config from open_webui.models.groups import Groups -from open_webui.models.users import Users from open_webui.utils.access_control import has_connection_access from open_webui.utils.auth import get_verified_user from open_webui.utils.terminals import get_terminal_server_url @@ -50,6 +49,10 @@ def _sanitize_proxy_path(path: str) -> str | None: # Fail closed: still encoded after the cap means the upstream would decode further into traversal. if unquote(decoded) != decoded: return None + # posixpath splits on '/' only, so 'a/..\..\b' survives normpath as one component. + # Upstreams that treat '\' as a separator would resolve it, so reject outright. + if '\\' in decoded: + return None had_trailing_slash = decoded.endswith('/') normalized = posixpath.normpath(decoded) # Remove any leading slashes that would reset the base @@ -97,6 +100,9 @@ async def proxy_terminal( if connection is None: return JSONResponse({'error': f"Terminal server '{server_id}' not found"}, status_code=404) + if not connection.get('enabled', True): + return JSONResponse({'error': 'Terminal server disabled'}, status_code=403) + user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id)} if not await has_connection_access(user, connection, user_group_ids): return JSONResponse({'error': 'Access denied'}, status_code=403) @@ -129,9 +135,18 @@ async def proxy_terminal( headers.update(bearer_auth_header(request.state.token.credentials)) elif auth_type == 'system_oauth': cookies = request.cookies - oauth_token = request.headers.get('x-oauth-access-token', '') + # Resolve the token server-side from the caller's OAuth session; never trust a client header. + oauth_token = None + try: + if request.cookies.get('oauth_session_id', None): + oauth_token = await request.app.state.oauth_manager.get_oauth_token( + user.id, + request.cookies.get('oauth_session_id', None), + ) + except Exception as e: + log.error(f'Error getting OAuth token: {e}') if oauth_token: - headers.update(bearer_auth_header(oauth_token)) + headers.update(bearer_auth_header(oauth_token.get('access_token', ''))) # auth_type == "none": no Authorization header content_type = request.headers.get('content-type') @@ -208,7 +223,7 @@ async def _resolve_authenticated_connection(ws: WebSocket, server_id: str): import asyncio import json - from open_webui.utils.auth import decode_token, is_valid_token + from open_webui.utils.auth import get_verified_user_by_token # First-message authentication try: @@ -217,14 +232,9 @@ async def _resolve_authenticated_connection(ws: WebSocket, server_id: str): if payload.get('type') != 'auth': await ws.close(code=4001, reason='Expected auth message') return None - token = payload.get('token', '') - data = decode_token(token) - if data is None or 'id' not in data or not await is_valid_token(data, getattr(ws.app.state, 'redis', None)): - await ws.close(code=4001, reason='Invalid token') - return None - user = await Users.get_user_by_id(data['id']) + user = await get_verified_user_by_token(payload.get('token', ''), getattr(ws.app.state, 'redis', None)) if user is None: - await ws.close(code=4001, reason='User not found') + await ws.close(code=4001, reason='Invalid token') return None except (asyncio.TimeoutError, json.JSONDecodeError): await ws.close(code=4001, reason='Auth timeout or invalid payload') @@ -241,6 +251,10 @@ async def _resolve_authenticated_connection(ws: WebSocket, server_id: str): await ws.close(code=4004, reason='Terminal server not found') return None + if not connection.get('enabled', True): + await ws.close(code=4003, reason='Terminal server disabled') + return None + user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id)} if not await has_connection_access(user, connection, user_group_ids): await ws.close(code=4003, reason='Access denied') diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py index b8ef51a280..f14b89d6ad 100644 --- a/backend/open_webui/routers/tools.py +++ b/backend/open_webui/routers/tools.py @@ -446,20 +446,22 @@ async def get_tools_by_id(id: str, user=Depends(get_verified_user), db: AsyncSes db=db, ) ): - return ToolAccessResponse( - **tools.model_dump(), - write_access=( - (user.role == 'admin' and BYPASS_ADMIN_ACCESS_CONTROL) - or user.id == tools.user_id - or await AccessGrants.has_access( - user_id=user.id, - resource_type='tool', - resource_id=tools.id, - permission='write', - db=db, - ) - ), + write_access = ( + (user.role == 'admin' and BYPASS_ADMIN_ACCESS_CONTROL) + or user.id == tools.user_id + or await AccessGrants.has_access( + user_id=user.id, + resource_type='tool', + resource_id=tools.id, + permission='write', + db=db, + ) ) + data = tools.model_dump() + if not write_access: + # extra='allow' re-admits content from model_dump; source is writer-only + data.pop('content', None) + return ToolAccessResponse(**data, write_access=write_access) else: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, diff --git a/backend/open_webui/routers/users.py b/backend/open_webui/routers/users.py index 54559c748e..01ea3aa5e4 100644 --- a/backend/open_webui/routers/users.py +++ b/backend/open_webui/routers/users.py @@ -1069,36 +1069,41 @@ async def get_user_preview( user_group_ids = {g.id for g in user_groups} all_models = await Models.get_all_models(db=db) - accessible_model_ids = await AccessGrants.get_accessible_resource_ids( + active_models = [m for m in all_models if m.is_active] + owned_model_ids = {m.id for m in active_models if m.user_id == user_id} + granted_model_ids = await AccessGrants.get_accessible_resource_ids( user_id=user_id, resource_type='model', - resource_ids=[m.id for m in all_models], + resource_ids=[m.id for m in active_models if m.user_id != user_id], permission='read', user_group_ids=user_group_ids, db=db, ) + accessible_model_ids = owned_model_ids | granted_model_ids all_knowledge = await Knowledges.get_knowledge_bases(db=db) - accessible_knowledge_ids = await AccessGrants.get_accessible_resource_ids( + owned_knowledge_ids = {k.id for k in all_knowledge if k.user_id == user_id} + granted_knowledge_ids = await AccessGrants.get_accessible_resource_ids( user_id=user_id, resource_type='knowledge', - resource_ids=[k.id for k in all_knowledge], + resource_ids=[k.id for k in all_knowledge if k.user_id != user_id], permission='read', user_group_ids=user_group_ids, db=db, ) + accessible_knowledge_ids = owned_knowledge_ids | granted_knowledge_ids all_tools = await Tools.get_tools(defer_content=True, db=db) - accessible_tool_ids = await AccessGrants.get_accessible_resource_ids( + owned_tool_ids = {t.id for t in all_tools if t.user_id == user_id} + granted_tool_ids = await AccessGrants.get_accessible_resource_ids( user_id=user_id, resource_type='tool', - resource_ids=[t.id for t in all_tools], + resource_ids=[t.id for t in all_tools if t.user_id != user_id], permission='read', user_group_ids=user_group_ids, db=db, ) - - active_models = [m for m in all_models if m.is_active] + accessible_tool_ids = owned_tool_ids | granted_tool_ids return { 'user': {'id': target_user.id, 'name': target_user.name}, diff --git a/backend/open_webui/socket/main.py b/backend/open_webui/socket/main.py index 67fbd5bcdd..46cc5719bb 100644 --- a/backend/open_webui/socket/main.py +++ b/backend/open_webui/socket/main.py @@ -31,12 +31,16 @@ from open_webui.env import ( from open_webui.models.access_grants import AccessGrants from open_webui.models.channels import Channels from open_webui.models.chats import Chats +from open_webui.models.folders import Folders from open_webui.models.notes import Notes, NoteUpdateForm from open_webui.models.users import UserNameResponse, Users from open_webui.socket.utils import RedisDict, RedisLock, YdocManager from open_webui.tasks import create_task, stop_item_tasks from open_webui.utils.access_control import has_permission -from open_webui.utils.auth import decode_token, is_valid_token +from open_webui.utils.auth import get_verified_user_by_token +from open_webui.utils.chat_id import is_saved_chat_id +from open_webui.utils.json_codec import SOCKETIO_JSON +from open_webui.utils.misc import get_output_text from open_webui.utils.redis import ( build_sentinel_url, get_redis_connection, @@ -60,29 +64,6 @@ def get_room_sid_map(manager, namespace: str, room: str): return manager.rooms.get(namespace, {}).get(room) -class LocalFilteredRedisManager(socketio.AsyncRedisManager): - """AsyncRedisManager that drops pub/sub emits with no local recipients. - - Every instance subscribed to the shared Socket.IO channel receives every - emit published by the whole fleet. Upstream ``_handle_emit`` re-encodes - the full packet before discovering the target room has no participants on - this instance, so each instance burns CPU serializing payloads addressed - to sessions it does not host — a cost that grows with instance count. - Bail out before that work when the room is empty here. Only string - rooms take the fast path; broadcasts (``room=None``) and any other - room shape (e.g. lists, which upstream indexes before validating) - always pass through unchanged. - """ - - async def _handle_emit(self, message): - room = message.get('room') - if isinstance(room, str): - namespace = message.get('namespace') or '/' - if not get_room_sid_map(self, namespace, room): - return - await super()._handle_emit(message) - - if WEBSOCKET_MANAGER == 'redis': sentinel_hosts = WEBSOCKET_SENTINEL_HOSTS or '' ws_redis_url = ( @@ -90,10 +71,11 @@ if WEBSOCKET_MANAGER == 'redis': if sentinel_hosts else WEBSOCKET_REDIS_URL ) - redis_manager = LocalFilteredRedisManager(ws_redis_url, redis_options=WEBSOCKET_REDIS_OPTIONS) + redis_manager = socketio.AsyncRedisManager(ws_redis_url, redis_options=WEBSOCKET_REDIS_OPTIONS, json=SOCKETIO_JSON) sio = socketio.AsyncServer( cors_allowed_origins=SOCKETIO_CORS_ORIGINS, async_mode='asgi', + json=SOCKETIO_JSON, transports=(['websocket'] if ENABLE_WEBSOCKET_SUPPORT else ['polling']), allow_upgrades=ENABLE_WEBSOCKET_SUPPORT, always_connect=True, @@ -107,6 +89,7 @@ else: sio = socketio.AsyncServer( cors_allowed_origins=SOCKETIO_CORS_ORIGINS, async_mode='asgi', + json=SOCKETIO_JSON, transports=(['websocket'] if ENABLE_WEBSOCKET_SUPPORT else ['polling']), allow_upgrades=ENABLE_WEBSOCKET_SUPPORT, always_connect=True, @@ -192,25 +175,31 @@ YDOC_MANAGER = YdocManager( async def periodic_session_pool_cleanup(): """Reap orphaned SESSION_POOL entries that missed heartbeats (e.g. crashed instance).""" - if not session_aquire_func(): - log.debug('Session cleanup lock held by another node. Skipping.') - return + retry_delay = random.uniform(WEBSOCKET_REDIS_LOCK_TIMEOUT / 2, WEBSOCKET_REDIS_LOCK_TIMEOUT) + while True: + if not session_aquire_func(): + log.debug('Session cleanup lock held by another node. Retrying.') + await asyncio.sleep(retry_delay) + continue - try: - while True: - if not session_renew_func(): - log.error('Unable to renew session cleanup lock. Exiting.') - return + try: + while True: + if not session_renew_func(): + log.warning('Unable to renew session cleanup lock. Retrying cleanup ownership.') + break - now = int(time.time()) - for sid in list(SESSION_POOL.keys()): - entry = SESSION_POOL.get(sid) - if entry and now - entry.get('last_seen_at', 0) > SESSION_POOL_TIMEOUT: - log.warning(f'Reaping orphaned session {sid} (user {entry.get("id")})') - del SESSION_POOL[sid] - await asyncio.sleep(SESSION_POOL_TIMEOUT) - finally: - session_release_func() + now = int(time.time()) + for sid in list(SESSION_POOL.keys()): + entry = SESSION_POOL.get(sid) + if entry and now - entry.get('last_seen_at', 0) > SESSION_POOL_TIMEOUT: + log.warning(f'Reaping orphaned session {sid} (user {entry.get("id")})') + try: + del SESSION_POOL[sid] + except KeyError: + pass + await asyncio.sleep(SESSION_POOL_TIMEOUT) + finally: + session_release_func() async def periodic_usage_pool_cleanup(): @@ -368,13 +357,10 @@ async def connect(sid, environ, auth): scope = (environ or {}).get('asgi.scope') or {} fastapi_app = scope.get('app') redis = getattr(getattr(fastapi_app, 'state', None), 'redis', None) or REDIS - data = decode_token(auth['token']) - - if data is not None and 'id' in data and await is_valid_token(data, redis): - user = await Users.get_user_by_id(data['id']) + user = await get_verified_user_by_token(auth['token'], redis) if user: - SESSION_POOL[sid] = { + socket_user = { **user.model_dump( exclude=[ 'profile_image_url', @@ -386,6 +372,8 @@ async def connect(sid, environ, auth): ), 'last_seen_at': int(time.time()), } + SESSION_POOL[sid] = socket_user + await sio.save_session(sid, {'user': socket_user}) await sio.enter_room(sid, f'user:{user.id}') @@ -399,42 +387,35 @@ async def user_join(sid, data): scope = environ.get('asgi.scope') or {} fastapi_app = scope.get('app') redis = getattr(getattr(fastapi_app, 'state', None), 'redis', None) or REDIS - token_data = decode_token(auth['token']) - if token_data is None or 'id' not in token_data or not await is_valid_token(token_data, redis): + user = await get_verified_user_by_token(auth['token'], redis) + if not user: return - existing = SESSION_POOL.get(sid) - if existing and existing.get('id') == token_data['id']: - SESSION_POOL[sid] = {**existing, 'last_seen_at': int(time.time())} - user_id, user_name, user_role = existing['id'], existing['name'], existing['role'] - else: - user = await Users.get_user_by_id(token_data['id']) - if not user: - return + socket_user = { + **user.model_dump( + exclude=[ + 'profile_image_url', + 'profile_banner_image_url', + 'date_of_birth', + 'bio', + 'gender', + ] + ), + 'last_seen_at': int(time.time()), + } - SESSION_POOL[sid] = { - **user.model_dump( - exclude=[ - 'profile_image_url', - 'profile_banner_image_url', - 'date_of_birth', - 'bio', - 'gender', - ] - ), - 'last_seen_at': int(time.time()), - } - await sio.enter_room(sid, f'user:{user.id}') - user_id, user_name, user_role = user.id, user.name, user.role + SESSION_POOL[sid] = socket_user + await sio.save_session(sid, {'user': socket_user}) + await sio.enter_room(sid, f'user:{user.id}') # Join all the channels only if user has channels permission - if user_role == 'admin' or await has_permission(user_id, 'features.channels'): - channels = await Channels.get_channels_by_user_id(user_id) + if user.role == 'admin' or await has_permission(user.id, 'features.channels'): + channels = await Channels.get_channels_by_user_id(user.id) log.debug(f'{channels=}') for channel in channels: await sio.enter_room(sid, f'channel:{channel.id}') - return {'id': user_id, 'name': user_name} + return {'id': user.id, 'name': user.name} @sio.on('heartbeat') @@ -455,11 +436,7 @@ async def join_channel(sid, data): scope = environ.get('asgi.scope') or {} fastapi_app = scope.get('app') redis = getattr(getattr(fastapi_app, 'state', None), 'redis', None) or REDIS - data = decode_token(auth['token']) - if data is None or 'id' not in data or not await is_valid_token(data, redis): - return - - user = await Users.get_user_by_id(data['id']) + user = await get_verified_user_by_token(auth['token'], redis) if not user: return @@ -481,11 +458,7 @@ async def join_note(sid, data): scope = environ.get('asgi.scope') or {} fastapi_app = scope.get('app') redis = getattr(getattr(fastapi_app, 'state', None), 'redis', None) or REDIS - token_data = decode_token(auth['token']) - if token_data is None or 'id' not in token_data or not await is_valid_token(token_data, redis): - return - - user = await Users.get_user_by_id(token_data['id']) + user = await get_verified_user_by_token(auth['token'], redis) if not user: return @@ -540,9 +513,35 @@ async def channel_events(sid, data): await Channels.update_member_last_read_at(data['channel_id'], user['id']) +async def get_folder_unread_counts(user_id: str) -> dict[str, int]: + folder_list = await Folders.get_folders_by_user_id(user_id) + parent_by_id = {folder.id: folder.parent_id for folder in folder_list} + unread_counts = dict.fromkeys(parent_by_id.keys(), 0) + + direct_unread_counts = await Chats.count_unread_by_folder_ids(user_id, list(parent_by_id.keys())) + for unread_folder_id, unread_count in direct_unread_counts.items(): + current_id = unread_folder_id + seen = set() + while current_id and current_id not in seen: + seen.add(current_id) + if current_id in unread_counts: + unread_counts[current_id] += unread_count + current_id = parent_by_id.get(current_id) + + return unread_counts + + @sio.on('events:chat') async def chat_events(sid, data): - user = SESSION_POOL.get(sid) + try: + session = await sio.get_session(sid) + user = session.get('user') + except KeyError: + user = None + + if not user: + user = SESSION_POOL.get(sid) + if not user: return @@ -550,11 +549,32 @@ async def chat_events(sid, data): event_type = event_data.get('type') if event_type == 'last_read_at': - await Chats.update_chat_last_read_at_by_id(data['chat_id'], user['id']) + read_update = await Chats.update_chat_last_read_at_by_id(data['chat_id'], user['id']) + if not read_update: + return + last_read_at, was_unread = read_update + response_data = { + 'chat_id': data['chat_id'], + 'last_read_at': last_read_at, + } + if was_unread: + response_data['folder_unread_counts'] = await get_folder_unread_counts(user['id']) + + await sio.emit( + 'events', + { + 'chat_id': data['chat_id'], + 'data': { + 'type': 'chat:list', + 'data': response_data, + }, + }, + room=f'user:{user["id"]}', + ) try: from open_webui.utils.timers import cancel_timers_for_chat - await cancel_timers_for_chat(data['chat_id'], 'chat.read') + await cancel_timers_for_chat(data['chat_id'], 'chat.read', user['id']) except Exception: log.exception('Failed to cancel chat.read timers for chat %s', data.get('chat_id')) @@ -887,19 +907,20 @@ async def _make_channel_emitter(request_info): state = {'last_emit_at': 0.0} THROTTLE_INTERVAL = 0.15 # ~6 updates/sec - async def _emit_channel_update(content: str, done: bool = False): + async def _emit_channel_update(content: str, done: bool = False, output: list | None = None): from open_webui.models.messages import MessageForm, Messages msg = await Messages.get_message_by_id(message_id) if not msg or msg.channel_id != channel_id: return - update_form = MessageForm(content=content) + update_form = MessageForm(content=content, data={'output': output} if output else None) if done: # Merge done flag into existing meta (preserve model_id etc.) existing_meta = msg.meta or {} update_form = MessageForm( content=content, + data={'output': output} if output else None, meta={**existing_meta, 'done': True}, ) @@ -924,16 +945,17 @@ async def _make_channel_emitter(request_info): if event_type == 'chat:completion': data = event_data.get('data', {}) - content = data.get('content', '') + output = data.get('output') + content = data.get('content') or get_output_text(output) done = data.get('done', False) - if not content and not done: + if not content and not output and not done: return now = __import__('time').time() if done or (now - state['last_emit_at']) >= THROTTLE_INTERVAL: state['last_emit_at'] = now - await _emit_channel_update(content, done) + await _emit_channel_update(content, done, output if isinstance(output, list) else None) elif event_type == 'chat:message:error': error = event_data.get('data', {}).get('error', {}) @@ -953,6 +975,7 @@ async def get_event_emitter(request_info, update_db=True): chat_id = request_info['chat_id'] message_id = request_info['message_id'] internal = request_info.get('internal') is True + save_to_chat = update_db and message_id and is_saved_chat_id(chat_id) if internal and event_data.get('type') == 'notification': return @@ -971,7 +994,7 @@ async def get_event_emitter(request_info, update_db=True): room=room, ) - if update_db and message_id and not (request_info.get('chat_id') or '').startswith('local:'): + if save_to_chat: event_type = event_data.get('type') if event_type == 'status': @@ -1097,6 +1120,11 @@ async def get_event_call(request_info): ) except TimeoutError: log.warning(f'Event caller timed out for session {session_id}') + if SESSION_POOL.get(session_id) == session: + try: + del SESSION_POOL[session_id] + except KeyError: + pass return {'error': 'Event call timed out. The browser tab may be inactive or closed.'} if 'session_id' in request_info and 'chat_id' in request_info and 'message_id' in request_info: diff --git a/backend/open_webui/socket/utils.py b/backend/open_webui/socket/utils.py index 010d1f34f6..00f8424aae 100644 --- a/backend/open_webui/socket/utils.py +++ b/backend/open_webui/socket/utils.py @@ -3,12 +3,12 @@ from __future__ import annotations import hashlib -import json import uuid import pycrdt as Y -from open_webui.utils.redis import get_redis_connection from open_webui.env import REDIS_KEY_PREFIX +from open_webui.utils.json_codec import JSONCodec +from open_webui.utils.redis import get_redis_connection YDOC_KEY_PREFIX = f'{REDIS_KEY_PREFIX}:ydoc:documents' @@ -16,6 +16,19 @@ YDOC_KEY_PREFIX = f'{REDIS_KEY_PREFIX}:ydoc:documents' class RedisLock: """Distributed lock backed by a Redis SET with NX/EX semantics.""" + _RENEW_SCRIPT = """ + if redis.call('get', KEYS[1]) == ARGV[1] then + return redis.call('expire', KEYS[1], ARGV[2]) + end + return 0 + """ + _RELEASE_SCRIPT = """ + if redis.call('get', KEYS[1]) == ARGV[1] then + return redis.call('del', KEYS[1]) + end + return 0 + """ + def __init__( self, redis_url, @@ -41,13 +54,10 @@ class RedisLock: return self.lock_obtained def renew_lock(self): - # xx=True will only set this key if it _has_ already been set - return self.redis.set(self.lock_name, self.lock_id, xx=True, ex=self.timeout_secs) + return bool(self.redis.eval(self._RENEW_SCRIPT, 1, self.lock_name, self.lock_id, self.timeout_secs)) def release_lock(self): - lock_value = self.redis.get(self.lock_name) - if lock_value and lock_value == self.lock_id: - self.redis.delete(self.lock_name) + self.redis.eval(self._RELEASE_SCRIPT, 1, self.lock_name, self.lock_id) class RedisDict: @@ -65,14 +75,14 @@ class RedisDict: ) def __setitem__(self, key, value): - serialized_value = json.dumps(value) + serialized_value = JSONCodec.dumps(value) self.redis.hset(self.name, key, serialized_value) def __getitem__(self, key): value = self.redis.hget(self.name, key) if value is None: raise KeyError(key) - return json.loads(value) + return JSONCodec.loads(value) def __delitem__(self, key): result = self.redis.hdel(self.name, key) @@ -89,10 +99,10 @@ class RedisDict: return self.redis.hkeys(self.name) def values(self): - return [json.loads(v) for v in self.redis.hvals(self.name)] + return [JSONCodec.loads(v) for v in self.redis.hvals(self.name)] def items(self): - return [(k, json.loads(v)) for k, v in self.redis.hgetall(self.name).items()] + return [(k, JSONCodec.loads(v)) for k, v in self.redis.hgetall(self.name).items()] def set(self, mapping: dict): if not mapping: @@ -101,7 +111,7 @@ class RedisDict: return # Serialize values once — reused for both the fingerprint and the write. - serialized = {k: json.dumps(v) for k, v in mapping.items()} + serialized = {k: JSONCodec.dumps(v) for k, v in mapping.items()} digest = hashlib.sha256() for key in sorted(serialized): digest.update(key.encode()) @@ -172,7 +182,7 @@ class YdocManager: document_id = document_id.replace(':', '_') if self._redis: redis_key = f'{self._redis_key_prefix}:{document_id}:updates' - await self._redis.rpush(redis_key, json.dumps(list(update))) + await self._redis.rpush(redis_key, JSONCodec.dumps(list(update))) list_len = await self._redis.llen(redis_key) if list_len >= self.COMPACTION_THRESHOLD: await self._compact_updates_redis(document_id) @@ -192,8 +202,8 @@ class YdocManager: mid = len(all_updates) // 2 ydoc = Y.Doc() for raw in all_updates[:mid]: - ydoc.apply_update(bytes(json.loads(raw))) - snapshot = json.dumps(list(ydoc.get_update())) + ydoc.apply_update(bytes(JSONCodec.loads(raw))) + snapshot = JSONCodec.dumps(list(ydoc.get_update())) pipe = self._redis.pipeline() pipe.delete(redis_key) pipe.rpush(redis_key, snapshot, *all_updates[mid:]) @@ -216,7 +226,7 @@ class YdocManager: if self._redis: redis_key = f'{self._redis_key_prefix}:{document_id}:updates' updates = await self._redis.lrange(redis_key, 0, -1) - return [bytes(json.loads(update)) for update in updates] + return [bytes(JSONCodec.loads(update)) for update in updates] else: return self._updates.get(document_id, []) diff --git a/backend/open_webui/tasks.py b/backend/open_webui/tasks.py index d6b2c00419..e5ff754297 100644 --- a/backend/open_webui/tasks.py +++ b/backend/open_webui/tasks.py @@ -2,10 +2,8 @@ import asyncio import json import logging -from typing import Dict, List, Optional from uuid import uuid4 -from fastapi import Request from redis.asyncio import Redis from open_webui.env import REDIS_KEY_PREFIX @@ -13,7 +11,7 @@ from open_webui.env import REDIS_KEY_PREFIX log = logging.getLogger(__name__) # A dictionary to keep track of active tasks -tasks: Dict[str, asyncio.Task] = {} +tasks: dict[str, asyncio.Task] = {} item_tasks = {} @@ -46,7 +44,7 @@ async def redis_task_command_listener(app): ### ------------------------------ -async def redis_save_task(redis: Redis, task_id: str, item_id: Optional[str]): +async def redis_save_task(redis: Redis, task_id: str, item_id: str | None): pipe = redis.pipeline() pipe.hset(REDIS_TASKS_KEY, task_id, item_id or '') if item_id: @@ -54,7 +52,7 @@ async def redis_save_task(redis: Redis, task_id: str, item_id: Optional[str]): await pipe.execute() -async def redis_cleanup_task(redis: Redis, task_id: str, item_id: Optional[str]): +async def redis_cleanup_task(redis: Redis, task_id: str, item_id: str | None): pipe = redis.pipeline() pipe.hdel(REDIS_TASKS_KEY, task_id) if item_id: @@ -67,11 +65,11 @@ async def redis_cleanup_task(redis: Redis, task_id: str, item_id: Optional[str]) await pipe.execute() -async def redis_list_tasks(redis: Redis) -> List[str]: +async def redis_list_tasks(redis: Redis) -> list[str]: return list(await redis.hkeys(REDIS_TASKS_KEY)) -async def redis_list_item_tasks(redis: Redis, item_id: str) -> List[str]: +async def redis_list_item_tasks(redis: Redis, item_id: str) -> list[str]: return list(await redis.smembers(f'{REDIS_ITEM_TASKS_KEY}:{item_id}')) @@ -101,11 +99,11 @@ async def cleanup_task(redis, task_id: str, id=None): item_tasks.pop(id, None) -async def create_task(redis, coroutine, id=None): +async def create_task(redis, coroutine, id=None, task_id=None): """ Create a new asyncio task and add it to the global task dictionary. """ - task_id = str(uuid4()) # Generate a unique ID for the task + task_id = task_id or str(uuid4()) # Generate a unique ID for the task task = asyncio.create_task(coroutine) # Create the task # Add a done callback for cleanup diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index 1d1bf8572d..03b18ca655 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -14,8 +14,14 @@ import logging import time from typing import Literal, Optional -from fastapi import Request +from fastapi import HTTPException, Request +from open_webui.config import RAG_EMBEDDING_QUERY_PREFIX +from open_webui.env import ( + KNOWLEDGE_GREP_MAX_MATCHES, + VIEW_FILE_DEFAULT_MAX_CHARS, + VIEW_FILE_MAX_CHARS, +) from open_webui.models.channels import Channel, ChannelMember, Channels from open_webui.models.chats import Chats from open_webui.models.config import Config @@ -52,6 +58,7 @@ from open_webui.routers.retrieval import search_web as _search_web from open_webui.tasks import stop_item_tasks from open_webui.events import EVENTS, publish_event from open_webui.socket.main import sio +from open_webui.utils.chat_id import is_saved_chat_id from open_webui.utils.notifications import notify_target from open_webui.utils.sanitize import sanitize_code @@ -378,7 +385,7 @@ async def generate_image( image_files = [{'type': 'image', 'url': img['url']} for img in images] # Persist files to DB if chat context is available - if __chat_id__ and __message_id__ and images: + if is_saved_chat_id(__chat_id__) and __message_id__ and images: db_files = await Chats.add_message_files_by_id_and_message_id( __chat_id__, __message_id__, @@ -446,7 +453,7 @@ async def edit_image( image_files = [{'type': 'image', 'url': img['url']} for img in images] # Persist files to DB if chat context is available - if __chat_id__ and __message_id__ and images: + if is_saved_chat_id(__chat_id__) and __message_id__ and images: db_files = await Chats.add_message_files_by_id_and_message_id( __chat_id__, __message_id__, @@ -2155,10 +2162,307 @@ async def search_knowledge_files( return json.dumps({'error': str(e)}) -# Hard cap for view_file / view_knowledge_file output -MAX_VIEW_FILE_CHARS = 100_000 -DEFAULT_VIEW_FILE_MAX_CHARS = 10_000 -MAX_GREP_RESULTS = 50 +async def _get_accessible_chat_files( + files: Optional[list[dict]], + user: dict, + file_id: Optional[str] = None, +) -> list[tuple[dict, object]]: + from open_webui.models.files import Files + + user_id = user.get('id') + user_role = user.get('role', 'user') + accessible = [] + seen = set() + + for item in files or []: + if not isinstance(item, dict) or item.get('type', 'file') != 'file': + continue + fid = item.get('id') or item.get('url') or '' + if ( + not isinstance(fid, str) + or not fid + or fid in seen + or fid.startswith(('http://', 'https://', 'data:')) + or (file_id and fid != file_id) + ): + continue + normalized = {**item, 'id': fid, 'type': 'file'} + if 'name' not in normalized and item.get('filename'): + normalized['name'] = item.get('filename') + seen.add(fid) + + file = await Files.get_file_by_id(fid) + if file and await _has_read_access_to_file(file, user_id, user_role): + accessible.append((normalized, file)) + + return accessible + + +def _grep_file_models( + files_to_search: list, + pattern: str, + case_insensitive: bool = False, + count_only: bool = False, +) -> str: + from open_webui.tools.knowledge_fs import build_matcher + + matches, err = build_matcher(pattern, case_insensitive) + if err: + return json.dumps({'error': err}) + + results = [] + total_matches = 0 + counts = [] + + for file in files_to_search: + content = '' + if file.data: + content = file.data.get('content', '') + if not content: + continue + + lines = content.split('\n') + file_matches = 0 + + for i, line in enumerate(lines, 1): + if matches(line): + file_matches += 1 + total_matches += 1 + if not count_only and len(results) < KNOWLEDGE_GREP_MAX_MATCHES: + results.append(f'{file.id} {file.filename}:{i}: {line}') + + if file_matches > 0 and count_only: + counts.append(f'{file.id} {file.filename}: {file_matches}') + + if count_only: + if not counts: + return f'No matches for "{pattern}"' + return '\n'.join(counts) + f'\n[{total_matches} total matches]' + + if not results: + return f'No matches for "{pattern}"' + + output = '\n'.join(results) + if total_matches > KNOWLEDGE_GREP_MAX_MATCHES: + output += f'\n[{KNOWLEDGE_GREP_MAX_MATCHES} of {total_matches} matches shown — use file_id to narrow]' + return output + + +async def list_chat_files( + __request__: Request = None, + __user__: dict = None, + __files__: list[dict] = None, +) -> str: + """ + List files attached to the current chat. + + :return: JSON with attached chat files containing id, filename, content type, size, and updated time when available + """ + if __request__ is None: + return json.dumps({'error': 'Request context not available'}) + + if not __user__: + return json.dumps({'error': 'User context not available'}) + + try: + files = [] + for item, file in await _get_accessible_chat_files(__files__, __user__): + file_info = { + 'id': file.id, + 'filename': file.filename, + 'name': item.get('name') or file.filename, + 'type': item.get('type', 'file'), + 'updated_at': file.updated_at, + } + content_type = item.get('content_type') or (file.meta or {}).get('content_type') + size = item.get('size') or (file.meta or {}).get('size') + if content_type: + file_info['content_type'] = content_type + if size: + file_info['size'] = size + files.append(file_info) + + return json.dumps(files, ensure_ascii=False) + except Exception as e: + log.exception(f'list_chat_files error: {e}') + return json.dumps({'error': str(e)}) + + +async def grep_chat_files( + pattern: str, + file_id: Optional[str] = None, + case_insensitive: bool = False, + count_only: bool = False, + __request__: Request = None, + __user__: dict = None, + __files__: list[dict] = None, +) -> str: + """ + Search exact text across files attached to the current chat. + Pass file_id from the attached_files block to search one file. + + :param pattern: The text pattern to search for + :param file_id: Optional attached file ID to search within a single file + :param case_insensitive: If true, ignore case when matching + :param count_only: If true, return only match counts per file + :return: Matching lines with file IDs, filenames, and line numbers + """ + if __request__ is None: + return json.dumps({'error': 'Request context not available'}) + + if not __user__: + return json.dumps({'error': 'User context not available'}) + + if not pattern or not pattern.strip(): + return json.dumps({'error': 'Pattern is required'}) + + if isinstance(file_id, str) and file_id.lower() in ('none', 'null', ''): + file_id = None + + try: + attached_ids = set() + for item in __files__ or []: + if not isinstance(item, dict) or item.get('type', 'file') != 'file': + continue + fid = item.get('id') or item.get('url') + if isinstance(fid, str) and fid and not fid.startswith(('http://', 'https://', 'data:')): + attached_ids.add(fid) + + if not attached_ids: + return json.dumps({'error': 'No files are attached to this chat'}) + if file_id and file_id not in attached_ids: + return json.dumps({'error': 'File not found'}) + + files_to_search = [file for _, file in await _get_accessible_chat_files(__files__, __user__, file_id)] + if not files_to_search: + return json.dumps({'error': 'No accessible files found'}) + + return _grep_file_models(files_to_search, pattern, case_insensitive, count_only) + except Exception as e: + log.exception(f'grep_chat_files error: {e}') + return json.dumps({'error': str(e)}) + + +async def query_chat_files( + query: str, + file_id: Optional[str] = None, + count: Optional[int] = None, + __request__: Request = None, + __user__: dict = None, + __files__: list[dict] = None, +) -> str: + """ + Search files attached to the current chat using semantic/vector search. + Pass file_id from the attached_files block to search one file, or omit it to search all attached chat files. + + :param query: The search query to find semantically relevant content + :param file_id: Optional attached file ID to search within a single file + :param count: Maximum number of results to return, capped by the server RAG top k + :return: JSON with relevant chunks containing content, source filename, and relevance score + """ + if __request__ is None: + return json.dumps({'error': 'Request context not available'}) + + if not __user__: + return json.dumps({'error': 'User context not available'}) + + if isinstance(file_id, str) and file_id.lower() in ('none', 'null', ''): + file_id = None + if isinstance(count, str): + if count.lower() in ('none', 'null', ''): + count = None + else: + try: + count = int(count) + except ValueError: + count = None + + try: + from open_webui.retrieval.utils import get_sources_from_items + + attached_ids = set() + for item in __files__ or []: + if not isinstance(item, dict) or item.get('type', 'file') != 'file': + continue + fid = item.get('id') or item.get('url') + if isinstance(fid, str) and fid and not fid.startswith(('http://', 'https://', 'data:')): + attached_ids.add(fid) + + if not attached_ids: + return json.dumps({'error': 'No files are attached to this chat'}) + if file_id and file_id not in attached_ids: + return json.dumps({'error': 'File not found'}) + + accessible = await _get_accessible_chat_files(__files__, __user__, file_id) + if not accessible: + return json.dumps({'error': 'No accessible files found'}) + + file_items = [{**item} for item, _ in accessible] + rag_config = await Config.get_many( + 'rag.top_k', + 'rag.top_k_reranker', + 'rag.relevance_threshold', + 'rag.hybrid_bm25_weight', + 'rag.enable_hybrid_search', + 'rag.full_context', + ) + top_k = rag_config.get('rag.top_k') or 5 + count = top_k if count is None else max(1, min(count, top_k)) + full_context = all(item.get('context') == 'full' for item in file_items) or rag_config.get('rag.full_context') + + embedding_function = getattr(__request__.app.state, 'EMBEDDING_FUNCTION', None) + if not embedding_function and not full_context: + return json.dumps({'error': 'Embedding function not configured'}) + + user_model = UserModel.model_construct( + id=__user__.get('id'), + role=__user__.get('role', 'user'), + ) + sources = await get_sources_from_items( + request=__request__, + items=file_items, + queries=[query], + embedding_function=( + lambda queries, prefix: embedding_function(queries, prefix=prefix, user=user_model) + if embedding_function + else None + ), + k=count, + reranking_function=( + (lambda q, docs: __request__.app.state.RERANKING_FUNCTION(q, docs, user=user_model)) + if getattr(__request__.app.state, 'RERANKING_FUNCTION', None) + else None + ), + k_reranker=rag_config.get('rag.top_k_reranker'), + r=rag_config.get('rag.relevance_threshold'), + hybrid_bm25_weight=rag_config.get('rag.hybrid_bm25_weight'), + hybrid_search=rag_config.get('rag.enable_hybrid_search'), + full_context=full_context, + user=user_model, + ) + + chunks = [] + for source in sources or []: + documents = source.get('document') or [] + metadatas = source.get('metadata') or [] + distances = source.get('distances') or [] + source_info = source.get('source') or {} + + for idx, doc in enumerate(documents): + metadata = metadatas[idx] if idx < len(metadatas) and isinstance(metadatas[idx], dict) else {} + chunk = { + 'content': doc, + 'source': metadata.get('source', metadata.get('name', source_info.get('name', 'Unknown'))), + 'file_id': metadata.get('file_id', source_info.get('id', '')), + } + if idx < len(distances): + chunk['distance'] = distances[idx] + chunks.append(chunk) + + return json.dumps(chunks[:count], ensure_ascii=False) + except Exception as e: + log.exception(f'query_chat_files error: {e}') + return json.dumps({'error': str(e)}) async def grep_knowledge_files( @@ -2194,16 +2498,11 @@ async def grep_knowledge_files( try: from open_webui.models.files import Files from open_webui.models.knowledge import Knowledges - from open_webui.tools.knowledge_fs import build_matcher user_id = __user__.get('id') user_role = __user__.get('role', 'user') user_group_ids = [group.id for group in await Groups.get_groups_by_member_id(user_id)] - _matches, err = build_matcher(pattern, case_insensitive) - if err: - return json.dumps({'error': err}) - # Collect files to search files_to_search = [] @@ -2279,43 +2578,7 @@ async def grep_knowledge_files( if not files_to_search: return json.dumps({'error': 'No accessible files found'}) - # Search - results = [] - total_matches = 0 - counts = [] - - for file in files_to_search: - content = '' - if file.data: - content = file.data.get('content', '') - if not content: - continue - - lines = content.split('\n') - file_matches = 0 - - for i, line in enumerate(lines, 1): - if _matches(line): - file_matches += 1 - total_matches += 1 - if not count_only and len(results) < MAX_GREP_RESULTS: - results.append(f'{file.id} {file.filename}:{i}: {line}') - - if file_matches > 0 and count_only: - counts.append(f'{file.id} {file.filename}: {file_matches}') - - if count_only: - if not counts: - return f'No matches for "{pattern}"' - return '\n'.join(counts) + f'\n[{total_matches} total matches]' - - if not results: - return f'No matches for "{pattern}"' - - output = '\n'.join(results) - if total_matches > MAX_GREP_RESULTS: - output += f'\n[{MAX_GREP_RESULTS} of {total_matches} matches shown — use file_id to narrow]' - return output + return _grep_file_models(files_to_search, pattern, case_insensitive, count_only) except Exception as e: log.exception(f'grep_knowledge_files error: {e}') @@ -2325,7 +2588,7 @@ async def grep_knowledge_files( async def view_file( file_id: str, offset: int = 0, - max_chars: int = DEFAULT_VIEW_FILE_MAX_CHARS, + max_chars: int = VIEW_FILE_DEFAULT_MAX_CHARS, line_numbers: bool = False, start_line: Optional[int] = None, end_line: Optional[int] = None, @@ -2338,7 +2601,7 @@ async def view_file( :param file_id: The ID of the file to retrieve :param offset: Character offset to start reading from (default: 0) - :param max_chars: Maximum characters to return (default: 10000, hard cap: 100000) + :param max_chars: Maximum characters to return (a server-side hard cap applies) :param line_numbers: If true, prefix each line with its 1-indexed line number :param start_line: Optional 1-indexed start line (overrides offset/max_chars when set) :param end_line: Optional 1-indexed end line (inclusive) @@ -2360,10 +2623,10 @@ async def view_file( try: max_chars = int(max_chars) except ValueError: - max_chars = DEFAULT_VIEW_FILE_MAX_CHARS + max_chars = VIEW_FILE_DEFAULT_MAX_CHARS # Enforce hard cap - max_chars = min(max(max_chars, 1), MAX_VIEW_FILE_CHARS) + max_chars = min(max(max_chars, 1), VIEW_FILE_MAX_CHARS) offset = max(offset, 0) try: @@ -2441,7 +2704,7 @@ async def view_file( async def view_knowledge_file( file_id: str, offset: int = 0, - max_chars: int = DEFAULT_VIEW_FILE_MAX_CHARS, + max_chars: int = VIEW_FILE_DEFAULT_MAX_CHARS, line_numbers: bool = False, start_line: Optional[int] = None, end_line: Optional[int] = None, @@ -2453,7 +2716,7 @@ async def view_knowledge_file( :param file_id: The ID of the file to retrieve :param offset: Character offset to start reading from (default: 0) - :param max_chars: Maximum characters to return (default: 10000, hard cap: 100000) + :param max_chars: Maximum characters to return (a server-side hard cap applies) :param line_numbers: If true, prefix each line with its 1-indexed line number :param start_line: Optional 1-indexed start line (overrides offset/max_chars when set) :param end_line: Optional 1-indexed end line (inclusive) @@ -2475,10 +2738,10 @@ async def view_knowledge_file( try: max_chars = int(max_chars) except ValueError: - max_chars = DEFAULT_VIEW_FILE_MAX_CHARS + max_chars = VIEW_FILE_DEFAULT_MAX_CHARS # Enforce hard cap - max_chars = min(max(max_chars, 1), MAX_VIEW_FILE_CHARS) + max_chars = min(max(max_chars, 1), VIEW_FILE_MAX_CHARS) offset = max(offset, 0) try: @@ -2781,9 +3044,10 @@ async def query_knowledge_files( user_role = __user__.get('role', 'user') user_group_ids = [group.id for group in await Groups.get_groups_by_member_id(user_id)] - embedding_function = __request__.app.state.EMBEDDING_FUNCTION + embedding_function = getattr(__request__.app.state, 'EMBEDDING_FUNCTION', None) if not embedding_function: return json.dumps({'error': 'Embedding function not configured'}) + user_model = UserModel.model_construct(id=user_id, role=user_role) collection_names = [] external_knowledges = [] @@ -2891,7 +3155,9 @@ async def query_knowledge_files( __request__, collection_names=collection_names, queries=[query], - embedding_function=embedding_function, + embedding_function=lambda queries, prefix: embedding_function( + queries, prefix=prefix, user=user_model + ), k=count, ) @@ -2916,7 +3182,7 @@ async def query_knowledge_files( knowledge, queries=[query], count=count, - user=type('UserContext', (), {'id': user_id, 'role': user_role})(), + user=user_model, ) documents = query_results.get('documents', [[]])[0] metadatas = query_results.get('metadatas', [[]])[0] @@ -2974,7 +3240,11 @@ async def query_knowledge_bases( user_id = __user__.get('id') user_group_ids = [group.id for group in await Groups.get_groups_by_member_id(user_id)] - query_embedding = await __request__.app.state.EMBEDDING_FUNCTION(query) + embedding_function = getattr(__request__.app.state, 'EMBEDDING_FUNCTION', None) + if not embedding_function: + return json.dumps({'error': 'Embedding function not configured'}) + user_model = UserModel.model_construct(id=user_id, role=__user__.get('role', 'user')) + query_embedding = await embedding_function(query, prefix=RAG_EMBEDDING_QUERY_PREFIX, user=user_model) # Min-heap of (distance, knowledge_base_id) - only holds top `count` results top_results_heap = [] @@ -3164,8 +3434,8 @@ async def create_tasks( :param tasks: List of task items. Each item: content (string, required), status (pending|in_progress|completed|cancelled, default pending), id (optional, auto-generated). :return: JSON with the full task list and summary counts """ - if __chat_id__ is None: - return json.dumps({'error': 'Chat context not available'}) + if not is_saved_chat_id(__chat_id__): + return json.dumps({'error': 'Saved chat context not available'}) try: all_tasks = [] @@ -3216,8 +3486,8 @@ async def update_task( :param status: New status: completed, in_progress, pending, or cancelled (default: completed) :return: JSON with the updated task list and summary counts """ - if __chat_id__ is None: - return json.dumps({'error': 'Chat context not available'}) + if not is_saved_chat_id(__chat_id__): + return json.dumps({'error': 'Saved chat context not available'}) try: status = status.strip().lower() @@ -3255,10 +3525,22 @@ async def update_task( # ============================================================================= +async def _validate_owned_automation_folder(user_id: str, folder_id: Optional[str]) -> Optional[str]: + if not folder_id: + return None + from open_webui.models.folders import Folders + + folder = await Folders.get_folder_by_id_and_user_id(folder_id, user_id) + if not folder: + raise ValueError('Folder not found') + return folder.id + + async def create_automation( name: str, prompt: str, rrule: str, + folder_id: Optional[str] = None, __request__: Request = None, __user__: dict = None, __metadata__: dict = None, @@ -3281,6 +3563,7 @@ async def create_automation( :param name: A short descriptive name for the automation :param prompt: The prompt/instructions to execute on each run :param rrule: An iCalendar RRULE string defining the schedule + :param folder_id: Optional owner-owned folder ID for generated chats :return: JSON with the created automation details including id, next scheduled runs """ if __request__ is None: @@ -3292,6 +3575,7 @@ async def create_automation( try: from open_webui.models.automations import AutomationData, AutomationForm, Automations from open_webui.models.users import Users + from open_webui.routers.automations import check_automation_limits from open_webui.utils.automations import next_n_runs_ns, next_run_ns, validate_rrule user_id = __user__.get('id') @@ -3307,15 +3591,26 @@ async def create_automation( if not model_id: return json.dumps({'error': 'Could not detect current model'}) + try: + folder_id = await _validate_owned_automation_folder(user_id, folder_id) + except ValueError as e: + return json.dumps({'error': str(e)}) + # Validate the RRULE try: validate_rrule(rrule, tz=user.timezone) except ValueError as e: return json.dumps({'error': f'Invalid schedule: {e}'}) + try: + await check_automation_limits(__request__, user, rrule, None, is_create=True) + except HTTPException as e: + return json.dumps({'error': e.detail}) + tz = user.timezone form = AutomationForm( name=name, + folder_id=folder_id, data=AutomationData( prompt=prompt, model_id=model_id, @@ -3331,6 +3626,7 @@ async def create_automation( 'status': 'success', 'id': automation.id, 'name': automation.name, + 'folder_id': automation.folder_id, 'model_id': model_id, 'is_active': automation.is_active, 'next_runs': next_n_runs_ns(rrule, tz=tz), @@ -3348,6 +3644,7 @@ async def update_automation( prompt: Optional[str] = None, rrule: Optional[str] = None, model_id: Optional[str] = None, + folder_id: Optional[str] = None, __request__: Request = None, __user__: dict = None, ) -> str: @@ -3359,6 +3656,7 @@ async def update_automation( :param prompt: New prompt/instructions (optional) :param rrule: New iCalendar RRULE schedule string (optional). See create_automation for format examples. :param model_id: New model ID to use (optional) + :param folder_id: New owner-owned folder ID (optional); pass an empty string to clear :return: JSON with the updated automation details """ if __request__ is None: @@ -3370,10 +3668,13 @@ async def update_automation( try: from open_webui.models.automations import AutomationData, AutomationForm, Automations from open_webui.models.users import Users + from open_webui.routers.automations import check_automation_limits from open_webui.utils.automations import next_n_runs_ns, next_run_ns, validate_rrule user_id = __user__.get('id') user = await Users.get_user_by_id(user_id) + if not user: + return json.dumps({'error': 'User not found'}) automation = await Automations.get_by_id(automation_id) if not automation: @@ -3386,17 +3687,30 @@ async def update_automation( new_prompt = prompt if prompt is not None else automation.data.get('prompt', '') new_model_id = model_id if model_id is not None else automation.data.get('model_id', '') new_rrule = rrule if rrule is not None else automation.data.get('rrule', '') + if folder_id is None: + new_folder_id = automation.folder_id + else: + try: + new_folder_id = await _validate_owned_automation_folder(user_id, folder_id) + except ValueError as e: + return json.dumps({'error': str(e)}) # Validate RRULE if changed if rrule is not None: try: - validate_rrule(new_rrule, tz=user.timezone if user else None) + validate_rrule(new_rrule, tz=user.timezone) except ValueError as e: return json.dumps({'error': f'Invalid schedule: {e}'}) - tz = user.timezone if user else None + try: + await check_automation_limits(__request__, user, new_rrule, None) + except HTTPException as e: + return json.dumps({'error': e.detail}) + + tz = user.timezone form = AutomationForm( name=new_name, + folder_id=new_folder_id, data=AutomationData( prompt=new_prompt, model_id=new_model_id, @@ -3412,6 +3726,7 @@ async def update_automation( 'status': 'success', 'id': updated.id, 'name': updated.name, + 'folder_id': updated.folder_id, 'model_id': new_model_id, 'is_active': updated.is_active, 'next_runs': next_n_runs_ns(new_rrule, tz=tz), @@ -3425,6 +3740,7 @@ async def update_automation( async def list_automations( status: Optional[str] = None, + folder_id: Optional[str] = None, count: int = 10, __request__: Request = None, __user__: dict = None, @@ -3433,6 +3749,7 @@ async def list_automations( List the user's scheduled automations. :param status: Filter by status: "active", "paused", or omit for all + :param folder_id: Optional owner-owned folder ID filter; pass an empty string to clear the folder filter :param count: Maximum number of automations to return (default: 10) :return: JSON list of automations with id, name, prompt snippet, schedule, status, and next runs """ @@ -3449,10 +3766,16 @@ async def list_automations( user_id = __user__.get('id') user = await Users.get_user_by_id(user_id) + if folder_id: + try: + folder_id = await _validate_owned_automation_folder(user_id, folder_id) + except ValueError as e: + return json.dumps({'error': str(e)}) result = await Automations.search_automations( user_id=user_id, status=status, + folder_id=folder_id, skip=0, limit=count, ) @@ -3467,6 +3790,7 @@ async def list_automations( { 'id': item.id, 'name': item.name, + 'folder_id': item.folder_id, 'prompt_snippet': snippet, 'model_id': item.data.get('model_id', ''), 'rrule': rrule, diff --git a/backend/open_webui/tools/knowledge_fs.py b/backend/open_webui/tools/knowledge_fs.py index 704ea45b1f..eed252ff2b 100644 --- a/backend/open_webui/tools/knowledge_fs.py +++ b/backend/open_webui/tools/knowledge_fs.py @@ -7,24 +7,58 @@ for AI models to interact with knowledge bases using commands they already know. Re-exported through builtin.py for consistent imports. """ +import contextvars import json import logging import re import shlex import time +from contextlib import contextmanager from typing import Optional +import regex from fastapi import Request +from open_webui.env import ( + KB_EXEC_MAX_GREP_FILES, + KB_EXEC_MAX_OUTPUT_CHARS, + KNOWLEDGE_GREP_MAX_MATCHES, +) + log = logging.getLogger(__name__) -# Limits -MAX_CAT_CHARS = 100_000 -DEFAULT_CAT_CHARS = 10_000 -MAX_GREP_FILES = 200 DEFAULT_HEAD_LINES = 10 DEFAULT_TAIL_LINES = 10 -MAX_GREP_MATCHES = 50 + +# Matching time allowed per tool call. Backtracking cost is exponential in the length of the +# matched text, so capping the pattern or the line does not bound it. +MATCH_BUDGET_SECONDS = 2.0 + + +class MatchBudgetExceeded(Exception): + """A tool call spent its whole matching budget, so the caller reports it.""" + + +class MatchBudget: + """Matching time remaining, counted only inside search() so awaits do not consume it.""" + + def __init__(self): + self.remaining = MATCH_BUDGET_SECONDS + + +# Scoped to the running task, so one budget covers every matcher a command builds without +# threading it through each handler. +_active_budget: contextvars.ContextVar[MatchBudget | None] = contextvars.ContextVar('kb_match_budget', default=None) + + +@contextmanager +def match_budget(): + """Bound the matching time of one tool call rather than of each search it runs.""" + token = _active_budget.set(MatchBudget()) + try: + yield + finally: + _active_budget.reset(token) # ============================================================================= @@ -59,11 +93,26 @@ def build_matcher(pattern: str, case_insensitive: bool = False, use_regex: bool if use_regex: normalized = normalize_regex(pattern) try: - re_flags = re.IGNORECASE if case_insensitive else 0 - compiled = re.compile(normalized, re_flags) - except re.error as e: + re_flags = regex.IGNORECASE if case_insensitive else 0 + compiled = regex.compile(normalized, re_flags) + except regex.error as e: return None, f'Invalid regex: {e}' - return (lambda line: bool(compiled.search(line))), None + + budget = _active_budget.get() or MatchBudget() + + def matches(line: str) -> bool: + started = time.monotonic() + try: + # A negative timeout disables it, so an exhausted budget must not reach search(). + if budget.remaining <= 0: + raise TimeoutError + return bool(compiled.search(line, timeout=budget.remaining)) + except TimeoutError: + raise MatchBudgetExceeded(f'Search exceeded {MATCH_BUDGET_SECONDS:g}s, narrow the pattern') from None + finally: + budget.remaining -= time.monotonic() - started + + return matches, None else: sp = pattern.lower() if case_insensitive else pattern return (lambda line: sp in (line.lower() if case_insensitive else line)), None @@ -579,21 +628,10 @@ async def _kb_cat(args: list[str], flags: set[str], user: dict, model_knowledge: return resolved['error'] content = resolved['content'] - show_numbers = 'n' in flags - - if len(content) > MAX_CAT_CHARS: - content = content[:MAX_CAT_CHARS] - truncated = True - else: - truncated = False - - if show_numbers: + if 'n' in flags: lines = content.split('\n') content = '\n'.join(f'{i}: {line}' for i, line in enumerate(lines, 1)) - if truncated: - content += f'\n[truncated at {MAX_CAT_CHARS:,} chars — use head/tail/sed/grep to navigate]' - return content @@ -742,7 +780,7 @@ async def _kb_grep( if ext_filter: accessible = [f for f in accessible if f['filename'].endswith(f'.{ext_filter}')] - if len(accessible) > MAX_GREP_FILES: + if len(accessible) > KB_EXEC_MAX_GREP_FILES: return f'Too many files ({len(accessible)}). Scope your search: grep "{pattern}" docs/ or grep "{pattern}" *.py' from open_webui.models.files import Files @@ -774,7 +812,7 @@ async def _kb_grep( if not count_only and not filenames_only: for line_num, line_text in file_matches: - if len(results) < MAX_GREP_MATCHES: + if len(results) < KNOWLEDGE_GREP_MAX_MATCHES: results.append(f'{file_info["id"]} {file_info["filename"]}:{line_num}: {line_text.rstrip()}') if count_only: @@ -793,8 +831,8 @@ async def _kb_grep( return f'No matches for "{pattern}" across {len(accessible)} files' output = '\n'.join(results) - if total_matches > MAX_GREP_MATCHES: - output += f'\n[showing {MAX_GREP_MATCHES} of {total_matches} matches]' + if total_matches > KNOWLEDGE_GREP_MAX_MATCHES: + output += f'\n[showing {KNOWLEDGE_GREP_MAX_MATCHES} of {total_matches} matches]' return output @@ -1131,7 +1169,15 @@ async def kb_exec( if not segments: return 'Could not parse command. Run kb_exec("ls") to start.' - return await _execute_pipeline(segments, __user__, __model_knowledge__) + # One budget for the whole command: a per-search budget would multiply by segment count. + with match_budget(): + output = await _execute_pipeline(segments, __user__, __model_knowledge__) + if len(output) > KB_EXEC_MAX_OUTPUT_CHARS: + output = output[:KB_EXEC_MAX_OUTPUT_CHARS] + ( + f'\n[output truncated at {KB_EXEC_MAX_OUTPUT_CHARS:,} chars' + ' — narrow the command with a path, glob, head/tail/sed or grep]' + ) + return output except Exception as e: log.exception(f'kb_exec error: {e}') return f'Error: {e}' diff --git a/backend/open_webui/utils/access_control/__init__.py b/backend/open_webui/utils/access_control/__init__.py index 975008b4c1..a549dae0a0 100644 --- a/backend/open_webui/utils/access_control/__init__.py +++ b/backend/open_webui/utils/access_control/__init__.py @@ -3,9 +3,11 @@ from typing import Any from open_webui.config import DEFAULT_USER_PERMISSIONS from open_webui.models.access_grants import ( + has_anyone_read_access_grant, has_public_read_access_grant, has_public_write_access_grant, has_user_access_grant, + strip_anyone_access_grants, strip_user_access_grants, ) from open_webui.models.groups import Groups @@ -161,10 +163,16 @@ async def has_connection_access( if user.role == 'admin' and BYPASS_ADMIN_ACCESS_CONTROL: return True + access_grants = (connection.get('config') or {}).get('access_grants', []) + if not access_grants: + # No grants configured → private, admin-only: admins must keep access + # to connections only they can configure, even when they do not bypass + # access control globally. + return user.role == 'admin' + if user_group_ids is None: user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id)} - access_grants = (connection.get('config') or {}).get('access_grants', []) return await has_access(user.id, 'read', access_grants, user_group_ids) @@ -215,13 +223,31 @@ async def filter_allowed_access_grants( user_role: str, access_grants: list, public_permission_key: str, + anyone_permission_key: str | None = None, db: AsyncSession | None = None, ) -> list: """ Checks if the user has the required permissions to grant access to a resource. Returns the filtered list of access grants if permissions are missing. """ - if user_role == 'admin' or not access_grants: + if not access_grants: + return access_grants + + if has_anyone_read_access_grant(access_grants) and ( + not anyone_permission_key + or ( + user_role != 'admin' + and not await has_permission( + user_id, + anyone_permission_key, + default_permissions, + db=db, + ) + ) + ): + access_grants = strip_anyone_access_grants(access_grants) + + if user_role == 'admin': return access_grants # Check if user can share publicly @@ -358,9 +384,7 @@ async def check_model_access( raise HTTPException(status_code=403, detail='Model not found') # Enforce access on chained base models - if not await has_base_model_access( - user.id, model_info, user_role=user.role, user_group_ids=user_group_ids - ): + if not await has_base_model_access(user.id, model_info, user_role=user.role, user_group_ids=user_group_ids): raise HTTPException(status_code=403, detail='Model not found') else: if user.role != 'admin': diff --git a/backend/open_webui/utils/anthropic.py b/backend/open_webui/utils/anthropic.py index 52dd2ea36a..5a289c2444 100644 --- a/backend/open_webui/utils/anthropic.py +++ b/backend/open_webui/utils/anthropic.py @@ -126,6 +126,13 @@ def _finalize_openai_content(blocks: list) -> str | list: return blocks +def is_anthropic_messages_passthrough(url: str, api_config: dict | None = None) -> bool: + api_config = api_config or {} + provider = str(api_config.get('provider', '')).lower() + + return is_anthropic_url(url or '') or provider == 'litellm' + + def convert_anthropic_to_openai_payload( anthropic_payload: dict, passthrough_params: list[str] | str | None = None ) -> dict: @@ -192,6 +199,8 @@ def convert_anthropic_to_openai_payload( }, ) ) + elif block_type in ('thinking', 'redacted_thinking'): + openai_content.append(_copy_cache_control(block, dict(block))) elif block_type == 'image': source = block.get('source', {}) if source.get('type') == 'base64': @@ -492,6 +501,11 @@ def convert_openai_to_anthropic_response( if not isinstance(block, dict): continue + if block.get('type') == 'redacted_thinking': + content.append({k: v for k, v in block.items() if k in {'type', 'data'}}) + has_thinking = True + continue + thinking = block.get('thinking') or block.get('content') or block.get('text') if not thinking: continue @@ -530,19 +544,37 @@ def convert_openai_to_anthropic_response( ) # Usage - openai_usage = openai_response.get('usage', {}) + openai_usage = openai_response.get('usage') or {} + cache_creation = openai_usage.get('cache_creation_input_tokens') + cache_read = openai_usage.get('cache_read_input_tokens') + prompt_details = openai_usage.get('prompt_tokens_details') + if cache_read is None and isinstance(prompt_details, dict): + cache_read = prompt_details.get('cached_tokens') + + usage_input = openai_usage.get('input_tokens') + if usage_input is None: + prompt_tokens = openai_usage.get('prompt_tokens') + if prompt_tokens is not None: + usage_input = max(prompt_tokens - (cache_creation or 0) - (cache_read or 0), 0) + + usage_output = openai_usage.get('output_tokens') + if usage_output is None: + usage_output = openai_usage.get('completion_tokens') + usage = { - 'input_tokens': ( - input_tokens - if input_tokens is not None - else openai_usage.get('input_tokens', openai_usage.get('prompt_tokens', 0)) - ), - 'output_tokens': openai_usage.get('output_tokens', openai_usage.get('completion_tokens', 0)), + 'input_tokens': usage_input if usage_input is not None else (input_tokens if input_tokens is not None else 0), + 'output_tokens': usage_output if usage_output is not None else 0, } - if 'cache_creation_input_tokens' in openai_usage: - usage['cache_creation_input_tokens'] = openai_usage['cache_creation_input_tokens'] - if 'cache_read_input_tokens' in openai_usage: - usage['cache_read_input_tokens'] = openai_usage['cache_read_input_tokens'] + if cache_creation is not None: + usage['cache_creation_input_tokens'] = cache_creation + if cache_read is not None: + usage['cache_read_input_tokens'] = cache_read + if isinstance(openai_usage.get('output_tokens_details'), dict): + usage['output_tokens_details'] = openai_usage['output_tokens_details'] + if isinstance(openai_usage.get('server_tool_use'), dict): + usage['server_tool_use'] = openai_usage['server_tool_use'] + if openai_usage.get('service_tier') is not None: + usage['service_tier'] = openai_usage['service_tier'] return { 'id': openai_response.get('id', f'msg_{_uuid.uuid4().hex[:24]}'), @@ -556,7 +588,7 @@ def convert_openai_to_anthropic_response( } -async def openai_stream_to_anthropic_stream(openai_stream_generator, model: str = '', input_tokens: int = 0): +async def openai_stream_to_anthropic_stream(openai_stream_generator, model: str = '', input_tokens: int | None = None): """ Convert an OpenAI SSE streaming response to Anthropic Messages SSE format. @@ -574,6 +606,11 @@ async def openai_stream_to_anthropic_stream(openai_stream_generator, model: str message_id = f'msg_{_uuid.uuid4().hex[:24]}' output_tokens = 0 + cache_creation_input_tokens = None + cache_read_input_tokens = None + output_tokens_details = None + server_tool_use = None + service_tier = None stop_reason = 'end_turn' # Track content blocks with a running index. @@ -603,7 +640,7 @@ async def openai_stream_to_anthropic_stream(openai_stream_generator, model: str 'model': model, 'stop_reason': None, 'stop_sequence': None, - 'usage': {'input_tokens': input_tokens, 'output_tokens': 0}, + 'usage': {'input_tokens': input_tokens or 0, 'output_tokens': 0}, }, } yield f'event: message_start\ndata: {json.dumps(message_start)}\n\n'.encode() @@ -630,29 +667,47 @@ async def openai_stream_to_anthropic_stream(openai_stream_generator, model: str except (json.JSONDecodeError, TypeError): continue + usage_data = data.get('usage') + if isinstance(usage_data, dict): + cache_creation = usage_data.get('cache_creation_input_tokens') + cache_read = usage_data.get('cache_read_input_tokens') + prompt_details = usage_data.get('prompt_tokens_details') + if cache_read is None and isinstance(prompt_details, dict): + cache_read = prompt_details.get('cached_tokens') + + usage_input = usage_data.get('input_tokens') + if usage_input is None: + prompt_tokens = usage_data.get('prompt_tokens') + if prompt_tokens is not None: + usage_input = max(prompt_tokens - (cache_creation or 0) - (cache_read or 0), 0) + + usage_output = usage_data.get('output_tokens') + if usage_output is None: + usage_output = usage_data.get('completion_tokens') + + if usage_input is not None: + input_tokens = usage_input + if usage_output is not None: + output_tokens = usage_output + if cache_creation is not None: + cache_creation_input_tokens = cache_creation + if cache_read is not None: + cache_read_input_tokens = cache_read + if isinstance(usage_data.get('output_tokens_details'), dict): + output_tokens_details = usage_data['output_tokens_details'] + if isinstance(usage_data.get('server_tool_use'), dict): + server_tool_use = usage_data['server_tool_use'] + if usage_data.get('service_tier') is not None: + service_tier = usage_data['service_tier'] + choices = data.get('choices', []) if not choices: - # Check for usage in the final chunk - if data.get('usage'): - input_tokens = data['usage'].get( - 'input_tokens', data['usage'].get('prompt_tokens', input_tokens) - ) - output_tokens = data['usage'].get( - 'output_tokens', data['usage'].get('completion_tokens', output_tokens) - ) continue delta = choices[0].get('delta', {}) finish_reason = choices[0].get('finish_reason') message = choices[0].get('message') or {} - # Update usage if present - if data.get('usage'): - input_tokens = data['usage'].get('input_tokens', data['usage'].get('prompt_tokens', input_tokens)) - output_tokens = data['usage'].get( - 'output_tokens', data['usage'].get('completion_tokens', output_tokens) - ) - reasoning_content = ( delta.get('reasoning_content') or delta.get('reasoning') @@ -892,13 +947,27 @@ async def openai_stream_to_anthropic_stream(openai_stream_generator, model: str yield f'event: content_block_stop\ndata: {json.dumps(block_stop)}\n\n'.encode() # Emit message_delta with stop reason + usage = {'output_tokens': output_tokens} + if input_tokens is not None: + usage['input_tokens'] = input_tokens + if cache_creation_input_tokens is not None: + usage['cache_creation_input_tokens'] = cache_creation_input_tokens + if cache_read_input_tokens is not None: + usage['cache_read_input_tokens'] = cache_read_input_tokens + if output_tokens_details is not None: + usage['output_tokens_details'] = output_tokens_details + if server_tool_use is not None: + usage['server_tool_use'] = server_tool_use + if service_tier is not None: + usage['service_tier'] = service_tier + message_delta = { 'type': 'message_delta', 'delta': { 'stop_reason': stop_reason, 'stop_sequence': None, }, - 'usage': {'output_tokens': output_tokens}, + 'usage': usage, } yield f'event: message_delta\ndata: {json.dumps(message_delta)}\n\n'.encode() diff --git a/backend/open_webui/utils/auth.py b/backend/open_webui/utils/auth.py index f9d596e615..0384d6fcb9 100644 --- a/backend/open_webui/utils/auth.py +++ b/backend/open_webui/utils/auth.py @@ -488,8 +488,11 @@ async def get_current_user_by_api_key(request, api_key: str): return user +VERIFIED_USER_ROLES = {'user', 'admin'} + + def get_verified_user(user=Depends(get_current_user)): - if user.role not in {'user', 'admin'}: + if user.role not in VERIFIED_USER_ROLES: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.ACCESS_PROHIBITED, @@ -497,6 +500,19 @@ def get_verified_user(user=Depends(get_current_user)): return user +async def get_verified_user_by_token(token: str, redis=None): + """Resolve a verified user from a raw token, for WebSocket handshakes that run outside the HTTP dependency chain.""" + decoded = decode_token(token) + if decoded is None or 'id' not in decoded or not await is_valid_token(decoded, redis): + return None + + user = await Users.get_user_by_id(decoded['id']) + if user is None or user.role not in VERIFIED_USER_ROLES: + return None + + return user + + def get_admin_user(user=Depends(get_current_user)): if user.role != 'admin': raise HTTPException( diff --git a/backend/open_webui/utils/automations.py b/backend/open_webui/utils/automations.py index 3d317585ea..b0415bc1d1 100644 --- a/backend/open_webui/utils/automations.py +++ b/backend/open_webui/utils/automations.py @@ -25,6 +25,7 @@ from typing import Optional from uuid import uuid4 from zoneinfo import ZoneInfo +from dateutil import parser as date_parser from dateutil.rrule import rrulestr from fastapi import Request from fastapi.security import HTTPAuthorizationCredentials @@ -34,6 +35,7 @@ from open_webui.internal.db import get_async_db from open_webui.models.automations import AutomationModel, AutomationRuns, Automations from open_webui.models.chats import ChatForm, Chats from open_webui.models.config import Config +from open_webui.models.folders import Folders from open_webui.models.users import Users from open_webui.utils.auth import create_token from open_webui.utils.misc import parse_duration @@ -72,30 +74,46 @@ def _resolve_tz(tz: str = None) -> Optional[ZoneInfo]: def _parse_rule(s: str, now: Optional[datetime] = None): """Parse RRULE with clock-aligned DTSTART for sub-daily frequencies. - MINUTELY/HOURLY rules use a fixed epoch DTSTART (2000-01-01 00:00) + SECONDLY/MINUTELY/HOURLY rules use a fixed epoch DTSTART (2000-01-01 00:00) so intervals snap to clock boundaries (e.g. every 5min = :00, :05, :10). """ - raw = s.replace('RRULE:', '') - parts = dict(p.split('=', 1) for p in raw.split(';') if '=' in p) + lines = s.splitlines() + rule_count = sum(1 for line in lines if line.upper().startswith('RRULE:')) + if 'EXRULE' in s.upper(): + raise ValueError('EXRULE is not supported in recurrence rules') + if rule_count > 1: + raise ValueError('only one RRULE is supported per recurrence rule') + + rrule_line = next((line for line in lines if line.upper().startswith('RRULE:')), s) + raw = rrule_line.split(':', 1)[1] if rrule_line.upper().startswith('RRULE:') else rrule_line + parts = {k.upper(): v for k, v in (p.split('=', 1) for p in raw.split(';') if '=' in p)} freq = parts.get('FREQ', '') - if freq in ('MINUTELY', 'HOURLY'): + if freq in ('SECONDLY', 'MINUTELY', 'HOURLY'): epoch = datetime(2000, 1, 1, 0, 0, 0) - if ( - now is not None - and s.startswith('RRULE:') - and '\n' not in s - and '\r' not in s - and set(parts) <= {'FREQ', 'INTERVAL', 'BYMINUTE', 'BYSECOND'} - ): - try: - interval = int(parts.get('INTERVAL', '1')) - if interval > 0: - step = timedelta(minutes=interval) if freq == 'MINUTELY' else timedelta(hours=interval) - return rrulestr(s, dtstart=epoch + ((now - epoch) // step) * step, ignoretz=True) - except (TypeError, ValueError): - pass - return rrulestr(s, dtstart=epoch, ignoretz=True) + anchor = now or datetime.now() + rule = '\n'.join(line for line in lines if not line.upper().startswith('DTSTART')) or s + dtstart = next((line.rsplit(':', 1)[-1] for line in lines if line.upper().startswith('DTSTART')), None) + interval = int(parts.get('INTERVAL', '1')) + if interval < 1: + raise ValueError('RRULE INTERVAL must be a positive integer') + if freq == 'SECONDLY': + step = timedelta(seconds=interval) + elif freq == 'MINUTELY': + step = timedelta(minutes=interval) + else: + step = timedelta(hours=interval) + if dtstart: + start = date_parser.parse(dtstart, ignoretz=True) + emitted = ((anchor - start) // step) if anchor > start else 0 + if 'BYMINUTE' in parts: + emitted *= len(parts['BYMINUTE'].split(',')) + if 'BYSECOND' in parts: + emitted *= len(parts['BYSECOND'].split(',')) + if emitted <= 100_000: + return rrulestr(s, ignoretz=True) + anchor = epoch + ((anchor - epoch) // step) * step + return rrulestr(rule, dtstart=anchor, ignoretz=True) return rrulestr(s, ignoretz=True) @@ -430,7 +448,10 @@ async def execute_automation(app, automation: AutomationModel) -> None: prompt = await prompt_template(automation.data['prompt'], user) model_id = automation.data['model_id'] - terminal_config = automation.data.get('terminal') + folder_id = automation.folder_id + if folder_id and not await Folders.get_folder_by_id_and_user_id(folder_id, automation.user_id): + await Automations.clear_folder_ids(automation.user_id, [folder_id]) + folder_id = None # Generate proper UUIDs for messages (same as frontend) user_msg_id = str(uuid4()) @@ -441,6 +462,7 @@ async def execute_automation(app, automation: AutomationModel) -> None: chat_id, automation.user_id, ChatForm( + folder_id=folder_id, chat={ 'title': automation.name, 'models': [model_id], @@ -472,7 +494,7 @@ async def execute_automation(app, automation: AutomationModel) -> None: {'role': 'user', 'content': prompt}, ], 'meta': {'automation_id': automation.id}, - } + }, ), ) diff --git a/backend/open_webui/utils/chat.py b/backend/open_webui/utils/chat.py index 2850c92b93..fda6320749 100644 --- a/backend/open_webui/utils/chat.py +++ b/backend/open_webui/utils/chat.py @@ -11,7 +11,6 @@ from aiocache import cached from fastapi import HTTPException, Request, status from open_webui.env import BYPASS_MODEL_ACCESS_CONTROL, GLOBAL_LOG_LEVEL from open_webui.functions import generate_function_chat_completion -from open_webui.models.functions import Functions from open_webui.models.models import Models from open_webui.models.users import UserModel from open_webui.routers.ollama import ( @@ -30,7 +29,7 @@ from open_webui.socket.main import ( sio, ) from open_webui.utils.filter import ( - get_sorted_filter_ids, + get_filter_functions, process_filter_functions, ) from open_webui.utils.models import check_model_access, get_all_models @@ -362,11 +361,11 @@ async def chat_completed(request: Request, form_data: dict, user: Any): } try: - filter_ids = await get_sorted_filter_ids(request, model, metadata.get('filter_ids', [])) - filter_functions = await Functions.get_functions_by_ids(filter_ids) + filter_functions = await get_filter_functions(request, model, metadata.get('filter_ids', [])) result, _ = await process_filter_functions( request=request, + filter_context=None, filter_functions=filter_functions, filter_type='outlet', form_data=data, diff --git a/backend/open_webui/utils/chat_id.py b/backend/open_webui/utils/chat_id.py new file mode 100644 index 0000000000..47b5e61174 --- /dev/null +++ b/backend/open_webui/utils/chat_id.py @@ -0,0 +1,27 @@ +from typing import Optional + + +TEMPORARY_CHAT_ID_PREFIX = 'temporary:' +LEGACY_TEMPORARY_CHAT_ID_PREFIX = 'local:' # Legacy temporary chat prefix. +CHANNEL_CHAT_ID_PREFIX = 'channel:' + +TEMPORARY_CHAT_ID_PREFIXES = ( + TEMPORARY_CHAT_ID_PREFIX, + LEGACY_TEMPORARY_CHAT_ID_PREFIX, +) +NON_SAVED_CHAT_ID_PREFIXES = (*TEMPORARY_CHAT_ID_PREFIXES, CHANNEL_CHAT_ID_PREFIX) + + +def is_saved_chat_id(chat_id: Optional[str]) -> bool: + return bool(chat_id) and not chat_id.startswith(NON_SAVED_CHAT_ID_PREFIXES) + + +def is_temporary_chat_id(chat_id: Optional[str]) -> bool: + return bool(chat_id) and chat_id.startswith(TEMPORARY_CHAT_ID_PREFIXES) + + +def get_temporary_chat_session_id(chat_id: str) -> Optional[str]: + for prefix in TEMPORARY_CHAT_ID_PREFIXES: + if chat_id.startswith(prefix): + return chat_id.removeprefix(prefix) + return None diff --git a/backend/open_webui/utils/context_compaction.py b/backend/open_webui/utils/context_compaction.py index 1a9b5e9f96..e3c6f54e2a 100644 --- a/backend/open_webui/utils/context_compaction.py +++ b/backend/open_webui/utils/context_compaction.py @@ -7,6 +7,7 @@ from typing import Any from fastapi.responses import JSONResponse from open_webui.models.chats import Chats from open_webui.models.config import Config +from open_webui.utils.chat_id import is_saved_chat_id from open_webui.utils.misc import get_content_from_message, get_last_user_message, get_message_list from open_webui.utils.task import ( get_task_model_id, @@ -51,16 +52,19 @@ async def compact_messages_for_request( if not config['enable']: return messages, None, False + system_messages = [messages[0]] if messages and messages[0].get('role') == 'system' else [] + messages = messages[1:] if system_messages else messages + messages, previous_summary = _apply_latest_summary_checkpoint(messages) token_threshold = _resolve_token_threshold(config['token_threshold'], config['token_cap'], metadata) if not _exceeds_token_threshold(messages, system_prompt, previous_summary, token_threshold) or len(messages) <= 3: - return messages, previous_summary, False + return [*system_messages, *messages], previous_summary, False boundary = _find_compaction_boundary(messages, config['retention_percentage']) compacted_messages = messages[:boundary] recent_messages = messages[boundary:] if not compacted_messages or not recent_messages: - return messages, previous_summary, False + return [*system_messages, *messages], previous_summary, False event_emitter = None if metadata.get('chat_id') and metadata.get('message_id'): @@ -110,7 +114,7 @@ async def compact_messages_for_request( checkpoint_message_id = ( recent_messages[0].get('id') or metadata.get('user_message_id') or metadata.get('message_id') ) - if chat_id and checkpoint_message_id and not chat_id.startswith(('local:', 'channel:')): + if is_saved_chat_id(chat_id) and checkpoint_message_id: await Chats.upsert_message_to_chat_by_id_and_message_id( chat_id, checkpoint_message_id, @@ -140,7 +144,7 @@ async def compact_messages_for_request( } ) - return recent_messages, summary, True + return [*system_messages, *recent_messages], summary, True async def compact_chat_branch(request, user, chat: Any, model_id: str, models: dict) -> dict: @@ -204,9 +208,7 @@ async def _load_config() -> dict: 'enable': bool(values.get('chat.context_compaction.enable', False)), 'token_threshold': token_threshold, 'token_cap': _parse_positive_int(values.get('chat.context_compaction.token_cap')) or token_threshold, - 'retention_percentage': _clamp_retention_percentage( - values.get('chat.context_compaction.retention_percentage') - ), + 'retention_percentage': _clamp_retention_percentage(values.get('chat.context_compaction.retention_percentage')), 'prompt_template': values.get('chat.context_compaction.prompt_template', '') or '', } @@ -260,9 +262,25 @@ async def get_chat_context_usage(chat: Any, model_id: str | None = None) -> dict for idx in range(len(messages) - 1, -1, -1): usage = messages[idx].get('usage') or (messages[idx].get('info') or {}).get('usage') - input_tokens = (usage or {}).get('input_tokens') or (usage or {}).get('prompt_tokens') - if isinstance(usage, dict) and input_tokens: - tokens = int(input_tokens or 0) + int(usage.get('output_tokens') or usage.get('completion_tokens') or 0) + if isinstance(usage, dict) and ( + tokens := ( + int( + usage.get('prompt_tokens') + or usage.get('input_tokens') + or usage.get('prompt_eval_count') + or usage.get('prompt_n') + or 0 + ) + + int( + usage.get('completion_tokens') + or usage.get('output_tokens') + or usage.get('eval_count') + or usage.get('predicted_n') + or 0 + ) + + int(usage.get('cache_n') or 0) + ) + ): tokens += _estimate_messages_tokens(messages[idx + 1 :]) return _build_context_usage(tokens, threshold) @@ -301,9 +319,26 @@ def _exceeds_token_threshold(messages: list[dict], system_prompt: str, summary: for idx in range(len(messages) - 1, -1, -1): usage = messages[idx].get('usage') or (messages[idx].get('info') or {}).get('usage') - if isinstance(usage, dict) and usage.get('input_tokens'): - total = int(usage.get('input_tokens') or 0) + int(usage.get('output_tokens') or 0) - return total + _estimate_messages_tokens(messages[idx + 1 :]) > threshold + if isinstance(usage, dict) and ( + tokens := ( + int( + usage.get('prompt_tokens') + or usage.get('input_tokens') + or usage.get('prompt_eval_count') + or usage.get('prompt_n') + or 0 + ) + + int( + usage.get('completion_tokens') + or usage.get('output_tokens') + or usage.get('eval_count') + or usage.get('predicted_n') + or 0 + ) + + int(usage.get('cache_n') or 0) + ) + ): + return tokens + _estimate_messages_tokens(messages[idx + 1 :]) > threshold estimated = _estimate_tokens(system_prompt) + _estimate_tokens(summary or '') + _estimate_messages_tokens(messages) return estimated > threshold @@ -329,11 +364,21 @@ async def _generate_summary( ) -> str: from open_webui.utils.chat import generate_chat_completion - task_model_id = get_task_model_id( - model_id, - await Config.get('task.model.default'), - await Config.get('task.model.external'), - models, + task_config = await Config.get_many( + 'task.model.default', + 'task.model.external', + 'chat.context_compaction.model', + ) + context_compaction_model = task_config.get('chat.context_compaction.model') + task_model_id = ( + context_compaction_model + if context_compaction_model in models + else get_task_model_id( + model_id, + task_config.get('task.model.default'), + task_config.get('task.model.external'), + models, + ) ) if task_model_id not in models: task_model_id = model_id diff --git a/backend/open_webui/utils/filter.py b/backend/open_webui/utils/filter.py index f73278e7e2..7d8b3e0a78 100644 --- a/backend/open_webui/utils/filter.py +++ b/backend/open_webui/utils/filter.py @@ -8,27 +8,61 @@ from open_webui.utils.plugin import get_function_module_from_cache log = logging.getLogger(__name__) -async def get_function_module(request, function_id, load_from_db=True): +class FilterContext: + def __init__(self): + self.valves_by_id = None + self.function_valves = {} + self.user_valves = {} + + async def get_function_valves(self, filter_ids, filter_id, Valves): + if filter_id not in self.function_valves: + if self.valves_by_id is None: + self.valves_by_id = await Functions.get_function_valves_by_ids(filter_ids) + valves = self.valves_by_id.get(filter_id) + self.function_valves[filter_id] = Valves(**(valves if valves else {})) + return self.function_valves[filter_id] + + async def get_user_valves(self, filter_id, user_id, UserValves): + user_valves_key = (filter_id, user_id) + if user_valves_key not in self.user_valves: + self.user_valves[user_valves_key] = await get_user_valves(filter_id, user_id, UserValves) + return self.user_valves[user_valves_key] + + +async def get_user_valves(filter_id, user_id, UserValves): + user_valves_data = await Functions.get_user_valves_by_id_and_user_id(filter_id, user_id) + return UserValves(**(user_valves_data if user_valves_data else {})) + + +async def get_function_module(request, function_id, load_from_db=True, function=None): """ Get the function module by its ID. """ - function_module, _, _ = await get_function_module_from_cache(request, function_id, load_from_db=load_from_db) + function_module, _, _ = await get_function_module_from_cache( + request, function_id, function=function, load_from_db=load_from_db + ) return function_module -async def get_sorted_filter_ids(request, model: dict, enabled_filter_ids: list = None): - if not ENABLE_PLUGINS: - return [] - - active_filters = await Functions.get_active_filter_ids() +def get_model_filter_ids(model, active_filters): filter_ids = [fid for fid, is_global in active_filters if is_global] - if 'info' in model and 'meta' in model['info']: + if isinstance(model, dict) and 'info' in model and 'meta' in model['info']: filter_ids.extend(model['info']['meta'].get('filterIds', [])) filter_ids = list(set(filter_ids)) active_filter_ids = {fid for fid, _ in active_filters} + return [fid for fid in filter_ids if fid in active_filter_ids] + + +async def resolve_filter_pipeline(request, model: dict, enabled_filter_ids: list = None): + if not ENABLE_PLUGINS: + return [], [] + + active_filters = await Functions.get_active_filter_ids() + filter_ids = get_model_filter_ids(model, active_filters) + functions_by_id = {function.id: function for function in await Functions.get_functions_by_ids(filter_ids)} async def get_active_status(filter_id): - function_module = await get_function_module(request, filter_id) + function_module = await get_function_module(request, filter_id, function=functions_by_id.get(filter_id)) if getattr(function_module, 'toggle', None): return filter_id in (enabled_filter_ids or set()) @@ -36,17 +70,12 @@ async def get_sorted_filter_ids(request, model: dict, enabled_filter_ids: list = return True # Pre-compute active status for each filter (async functions can't be used in set comprehensions) - resolved_active = {} - for filter_id in active_filter_ids: - resolved_active[filter_id] = await get_active_status(filter_id) - active_filter_ids = {fid for fid, is_active in resolved_active.items() if is_active} - - filter_ids = [fid for fid in filter_ids if fid in active_filter_ids] + filter_ids = [fid for fid in filter_ids if await get_active_status(fid)] valves_by_id = await Functions.get_function_valves_by_ids(filter_ids) async def get_priority(function_id): try: - function_module = await get_function_module(request, function_id) + function_module = await get_function_module(request, function_id, function=functions_by_id.get(function_id)) if function_module and hasattr(function_module, 'Valves'): valves_db = valves_by_id.get(function_id) valves = function_module.Valves(**(valves_db if valves_db else {})) @@ -61,12 +90,118 @@ async def get_sorted_filter_ids(request, model: dict, enabled_filter_ids: list = priorities[fid] = await get_priority(fid) filter_ids.sort(key=lambda fid: (priorities.get(fid, 0), fid)) + filter_functions = [functions_by_id[fid] for fid in filter_ids if fid in functions_by_id] + return filter_ids, filter_functions + + +async def get_sorted_filter_ids(request, model: dict, enabled_filter_ids: list = None): + filter_ids, _ = await resolve_filter_pipeline(request, model, enabled_filter_ids) + return filter_ids +async def get_filter_functions(request, model: dict, enabled_filter_ids: list = None): + _, filter_functions = await resolve_filter_pipeline(request, model, enabled_filter_ids) + return filter_functions + + +async def apply_filter_valves(function_module, filter_context, valves_by_id, filter_ids, filter_id): + if not (hasattr(function_module, 'valves') and hasattr(function_module, 'Valves')): + return valves_by_id + + if filter_context is not None: + function_module.valves = await filter_context.get_function_valves(filter_ids, filter_id, function_module.Valves) + return valves_by_id + + if valves_by_id is None: + valves_by_id = await Functions.get_function_valves_by_ids(filter_ids) + valves = valves_by_id.get(filter_id) + function_module.valves = function_module.Valves(**(valves if valves else {})) + return valves_by_id + + +def get_filter_params(sig, filter_id, filter_type, form_data, extra_params): + params = {'event': form_data} if filter_type == 'stream' else {'body': form_data} + return params | { + k: v + for k, v in { + **extra_params, + '__id__': filter_id, + }.items() + if k in sig.parameters + } + + +async def apply_user_valves(function_module, filter_context, filter_id, params): + if '__user__' not in params or not hasattr(function_module, 'UserValves'): + return + + user_id = params['__user__'].get('id') + if filter_context is not None: + user_valves = await filter_context.get_user_valves(filter_id, user_id, function_module.UserValves) + else: + user_valves = await get_user_valves(filter_id, user_id, function_module.UserValves) + params['__user__']['valves'] = user_valves + + +async def run_filter_handler(handler, params): + if inspect.iscoroutinefunction(handler): + return await handler(**params) + return handler(**params) + + +async def process_filter_function( + request, + function, + filter_type, + form_data, + extra_params, + filter_context, + valves_by_id, + filter_ids, +): + filter_id = function.id + + function_module = await get_function_module( + request, filter_id, load_from_db=(filter_type != 'stream'), function=function + ) + handler = getattr(function_module, filter_type, None) + if not handler: + return form_data, valves_by_id, None + + skip_files = ( + function_module.file_handler if filter_type == 'inlet' and hasattr(function_module, 'file_handler') else None + ) + valves_by_id = await apply_filter_valves(function_module, filter_context, valves_by_id, filter_ids, filter_id) + + try: + sig = inspect.signature(handler) + params = get_filter_params(sig, filter_id, filter_type, form_data, extra_params) + + if '__user__' in sig.parameters: + try: + await apply_user_valves(function_module, filter_context, filter_id, params) + except Exception as e: + log.exception(f'Failed to get user values: {e}') + + form_data = await run_filter_handler(handler, params) + except Exception as e: + log.debug(f'Error in {filter_type} handler {filter_id}: {e}') + raise e + + return form_data, valves_by_id, skip_files + + # Grant these filters the discernment to pass what serves # and refuse what harms, for every soul in the house. -async def process_filter_functions(request, filter_functions, filter_type, form_data, extra_params): +async def process_filter_functions( + request, + filter_context, + filter_functions, + filter_type, + form_data, + extra_params, +): if not ENABLE_PLUGINS: return form_data, {} @@ -77,61 +212,18 @@ async def process_filter_functions(request, filter_functions, filter_type, form_ for function in filter_functions: if not function: continue - filter_id = function.id - function_module = await get_function_module(request, filter_id, load_from_db=(filter_type != 'stream')) - # Prepare handler function - handler = getattr(function_module, filter_type, None) - if not handler: - continue - - # Check if the function has a file_handler variable - if filter_type == 'inlet' and hasattr(function_module, 'file_handler'): - skip_files = function_module.file_handler - - # Apply valves to the function - if hasattr(function_module, 'valves') and hasattr(function_module, 'Valves'): - if valves_by_id is None: - valves_by_id = await Functions.get_function_valves_by_ids(filter_ids) - valves = valves_by_id.get(filter_id) - function_module.valves = function_module.Valves(**(valves if valves else {})) - - try: - # Prepare parameters - sig = inspect.signature(handler) - - params = {'body': form_data} - if filter_type == 'stream': - params = {'event': form_data} - - params = params | { - k: v - for k, v in { - **extra_params, - '__id__': filter_id, - }.items() - if k in sig.parameters - } - - # Handle user parameters - if '__user__' in sig.parameters: - if hasattr(function_module, 'UserValves'): - try: - params['__user__']['valves'] = function_module.UserValves( - **await Functions.get_user_valves_by_id_and_user_id(filter_id, params['__user__']['id']) - ) - except Exception as e: - log.exception(f'Failed to get user values: {e}') - - # Execute handler - if inspect.iscoroutinefunction(handler): - form_data = await handler(**params) - else: - form_data = handler(**params) - - except Exception as e: - log.debug(f'Error in {filter_type} handler {filter_id}: {e}') - raise e + form_data, valves_by_id, file_handler = await process_filter_function( + request, + function, + filter_type, + form_data, + extra_params, + filter_context, + valves_by_id, + filter_ids, + ) + skip_files = skip_files or file_handler # Handle file cleanup for inlet if skip_files: diff --git a/backend/open_webui/utils/headers.py b/backend/open_webui/utils/headers.py index f7b7297083..2f23879c8a 100644 --- a/backend/open_webui/utils/headers.py +++ b/backend/open_webui/utils/headers.py @@ -13,9 +13,12 @@ from open_webui.env import ( FORWARD_USER_INFO_HEADER_USER_NAME, FORWARD_USER_INFO_HEADER_USER_ROLE, ) +from open_webui.models.groups import Groups log = logging.getLogger(__name__) +USER_GROUPS_PLACEHOLDERS = ('{{USER_GROUPS}}', '{{USER_GROUP_IDS}}') + def _mint_forward_user_jwt(user: Any) -> str: now = int(time.time()) @@ -59,7 +62,36 @@ def include_user_info_headers(headers: dict, user: Optional[Any] = None) -> dict } -def get_custom_headers(custom_headers: dict, user=None, metadata: dict = None, request=None) -> dict: +def custom_headers_require_user_groups(custom_headers: Optional[dict]) -> bool: + if not custom_headers or not isinstance(custom_headers, dict): + return False + return any( + placeholder in str(value) for value in custom_headers.values() for placeholder in USER_GROUPS_PLACEHOLDERS + ) + + +async def get_user_groups_for_custom_headers( + custom_headers: Optional[dict], user: Optional[Any] = None +) -> Optional[list]: + """Fetch the user's groups only when a header value actually references a groups placeholder.""" + if user is None or not custom_headers_require_user_groups(custom_headers): + return None + + try: + return await Groups.get_groups_by_member_id(user.id) + except Exception: + log.exception('Failed to resolve user groups for custom headers') + return None + + +async def get_custom_headers(custom_headers: dict, user=None, metadata: dict = None, request=None) -> dict: + user_groups = await get_user_groups_for_custom_headers(custom_headers, user) + return parse_custom_headers(custom_headers, user, metadata, request=request, user_groups=user_groups) + + +def parse_custom_headers( + custom_headers: dict, user=None, metadata: dict = None, request=None, user_groups: Optional[list] = None +) -> dict: if not custom_headers or not isinstance(custom_headers, dict): return {} @@ -93,6 +125,8 @@ def get_custom_headers(custom_headers: dict, user=None, metadata: dict = None, r '{{USER_NAME}}': (user.name.strip() if user else '') or '', '{{USER_EMAIL}}': (user.email.strip() if user else '') or '', '{{USER_ROLE}}': (user.role if user else '') or '', + '{{USER_GROUPS}}': ','.join(group.name.strip() for group in user_groups) if user_groups else '', + '{{USER_GROUP_IDS}}': ','.join(group.id for group in user_groups) if user_groups else '', '{{USER_AGENT}}': user_agent, } diff --git a/backend/open_webui/utils/json_codec.py b/backend/open_webui/utils/json_codec.py new file mode 100644 index 0000000000..0e5bdbd1b5 --- /dev/null +++ b/backend/open_webui/utils/json_codec.py @@ -0,0 +1,50 @@ +"""The app-wide JSON codec, selected by the ``ENABLE_ORJSON`` env var. + +Every module that would otherwise reach for stdlib ``json`` imports ``JSONCodec`` +from here, so the whole app switches implementation from a single flag. With the +flag off these are stdlib ``json`` and engineio's codec verbatim, so the default +behaviour is exactly what it was before orjson entered the picture. +""" + +from __future__ import annotations + +import json as stdlib_json + +from engineio import json as engineio_json + +from open_webui.env import ENABLE_ORJSON + +if ENABLE_ORJSON: + import orjson + + class ORJSONCodec: + """stdlib-``json``-compatible codec backed by orjson. + + Anything orjson rejects (non-str dict keys, ints beyond 64 bits, ``NaN`` + literals) falls back to engineio's stdlib-based codec, which keeps its + oversized-integer guard for untrusted client payloads. + """ + + JSONDecodeError = engineio_json.JSONDecodeError + + @staticmethod + def dumps(obj, *args, **kwargs): + try: + return orjson.dumps(obj).decode('utf-8') + except (TypeError, ValueError): + return engineio_json.dumps(obj, *args, **kwargs) + + @staticmethod + def loads(s, *args, **kwargs): + try: + return orjson.loads(s) + except (TypeError, ValueError): + return engineio_json.loads(s, *args, **kwargs) + + # Drop-in for stdlib ``json``: ``JSONCodec.dumps`` / ``JSONCodec.loads``. + JSONCodec = ORJSONCodec + # Codec handed to the socket.io/engineio managers, which default to their own. + SOCKETIO_JSON = ORJSONCodec +else: + JSONCodec = stdlib_json + SOCKETIO_JSON = engineio_json diff --git a/backend/open_webui/utils/json_response.py b/backend/open_webui/utils/json_response.py new file mode 100644 index 0000000000..b6b31dd5d3 --- /dev/null +++ b/backend/open_webui/utils/json_response.py @@ -0,0 +1,55 @@ +"""orjson-backed JSON parsing/rendering for starlette/FastAPI requests and responses.""" + +from __future__ import annotations + +import json +from typing import Any + +from starlette.requests import Request +from starlette.responses import JSONResponse + +from open_webui.env import ENABLE_ORJSON + + +def apply_orjson_http_json() -> None: + """Parse request bodies and serialize ``JSONResponse`` with orjson. + + A no-op unless ``ENABLE_ORJSON`` is set, leaving starlette's own + stdlib-``json`` implementations untouched. + + Not ``FastAPI(default_response_class=...)`` on purpose: an explicit + default disables FastAPI's Pydantic direct-to-bytes fast path for + ``response_model`` routes. NaN/Infinity floats serialize as ``null`` + instead of raising. + """ + if not ENABLE_ORJSON: + return + + import orjson + + def render(self, content: Any) -> bytes: + try: + return orjson.dumps(content) + except (TypeError, ValueError): + # Fallback matches starlette's JSONResponse.render exactly. + return json.dumps( + content, + ensure_ascii=False, + allow_nan=False, + indent=None, + separators=(',', ':'), + ).encode('utf-8') + + async def request_json(self) -> Any: + if not hasattr(self, '_json'): + body = await self.body() + try: + self._json = orjson.loads(body) + except (TypeError, ValueError): + # Fallback matches starlette's Request.json exactly, including the + # json.JSONDecodeError that FastAPI turns into a 422. + self._json = json.loads(body) + return self._json + + JSONResponse.render = render + Request.json = request_json diff --git a/backend/open_webui/utils/logger.py b/backend/open_webui/utils/logger.py index 1f46000bd5..fb0d702ed4 100644 --- a/backend/open_webui/utils/logger.py +++ b/backend/open_webui/utils/logger.py @@ -17,6 +17,7 @@ from open_webui.env import ( ENABLE_OTEL_LOGS, GLOBAL_LOG_LEVEL, LOG_FORMAT, + LOGURU_DIAGNOSE, ) if TYPE_CHECKING: @@ -178,6 +179,7 @@ def start_logger(): _json_sink, level=GLOBAL_LOG_LEVEL, filter=audit_filter, + diagnose=LOGURU_DIAGNOSE, ) else: logger.add( @@ -185,6 +187,7 @@ def start_logger(): level=GLOBAL_LOG_LEVEL, format=stdout_format, filter=audit_filter, + diagnose=LOGURU_DIAGNOSE, ) if AUDIT_LOG_LEVEL != 'NONE' and ENABLE_AUDIT_LOGS_FILE: try: @@ -195,6 +198,7 @@ def start_logger(): compression='zip', format=file_format, filter=lambda record: record['extra'].get('auditable') is True, + diagnose=LOGURU_DIAGNOSE, ) except Exception as e: logger.error(f'Failed to initialize audit log file handler: {str(e)}') diff --git a/backend/open_webui/utils/memory.py b/backend/open_webui/utils/memory.py index 5cec5153ff..ca84517c1d 100644 --- a/backend/open_webui/utils/memory.py +++ b/backend/open_webui/utils/memory.py @@ -422,7 +422,7 @@ async def review_memory_after_turn( if not features.get('memory'): return - assistant_content = assistant_message.get('content', '') + assistant_content = get_content_from_message(assistant_message) if not isinstance(assistant_content, str) or not assistant_content.strip(): return @@ -479,9 +479,9 @@ async def _review_memory( for memory in (existing_memories or [])[:80] ] - assistant_content = assistant_message.get('content', '') + assistant_content = get_content_from_message(assistant_message) if not isinstance(assistant_content, str): - assistant_content = get_content_from_message(assistant_message) + assistant_content = '' transcript_lines = [] for message in messages[-16:]: diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index f1fc6c39d6..4f8ecf4a7c 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -43,7 +43,6 @@ from open_webui.env import ( from open_webui.models.chats import Chats from open_webui.models.config import Config from open_webui.models.folders import Folders -from open_webui.models.functions import Functions from open_webui.models.models import Models from open_webui.models.notes import Notes from open_webui.models.oauth_sessions import OAuthSessions @@ -80,6 +79,7 @@ from open_webui.utils.access_control import has_connection_access, has_permissio from open_webui.models.access_grants import AccessGrants from open_webui.utils.access_control.folders import has_folder_access from open_webui.utils.chat import generate_chat_completion +from open_webui.utils.chat_id import is_saved_chat_id from open_webui.utils.code_interpreter import execute_code_jupyter from open_webui.utils.context_compaction import compact_messages_for_request from open_webui.utils.files import ( @@ -89,10 +89,12 @@ from open_webui.utils.files import ( get_image_url_from_base64, ) from open_webui.utils.filter import ( - get_sorted_filter_ids, + FilterContext, + get_filter_functions, process_filter_functions, ) +from open_webui.utils.json_codec import JSONCodec from open_webui.utils.mcp.client import MCPClient from open_webui.utils.memory import add_memory_context, review_memory_after_turn from open_webui.utils.misc import ( @@ -127,6 +129,7 @@ from open_webui.utils.task import ( ) from open_webui.utils.tools import ( build_tool_server_headers, + get_attached_knowledge, get_builtin_tools, get_terminal_tools, get_tools, @@ -142,7 +145,7 @@ async def publish_chat_finished_event( request: Request, user: UserModel, metadata: dict, title: str, content: str, output: list | None = None ): chat_id = metadata.get('chat_id') - if getattr(request.state, 'internal', False) is True or not chat_id or chat_id.startswith(('channel:', 'local:')): + if getattr(request.state, 'internal', False) is True or not is_saved_chat_id(chat_id): return content = content or get_output_text(output) @@ -166,7 +169,8 @@ async def publish_chat_finished_event( ) event_emitter = await get_event_emitter(metadata, update_db=False) if event_emitter: - await event_emitter({'type': 'chat:list', 'data': {'chat_id': chat_id}}) + folder_id = metadata.get('folder_id') or await Chats.get_chat_folder_id(chat_id, metadata.get('user_id')) + await event_emitter({'type': 'chat:list', 'data': {'chat_id': chat_id, 'folder_id': folder_id}}) # We believe in one maker of all models, seen and unseen, @@ -188,6 +192,12 @@ DEFAULT_SOLUTION_TAGS = [('<|begin_of_solution|>', '<|end_of_solution|>')] DEFAULT_CODE_INTERPRETER_TAGS = [('', '')] +def _start_tag_pattern(start_tag: str) -> str: + if start_tag.startswith('<') and start_tag.endswith('>'): + return rf'<{re.escape(start_tag[1:-1])}(\s.*?)?>' + return re.escape(start_tag) + + def output_id(prefix: str) -> str: """Generate OR-style ID: prefix + 24-char hex UUID.""" return f'{prefix}_{uuid4().hex[:24]}' @@ -230,6 +240,9 @@ def _split_tool_calls( """ def split_json_objects(raw: str) -> list[str]: + if not isinstance(raw, str): + raw = '' if raw is None else json.dumps(raw) + decoder = json.JSONDecoder() results = [] position = 0 @@ -250,7 +263,11 @@ def _split_tool_calls( expanded = [] for tool_call in tool_calls: - arguments = tool_call.get('function', {}).get('arguments', '') + function = tool_call.setdefault('function', {}) + arguments = function.get('arguments') + if not isinstance(arguments, str): + arguments = '' if arguments is None else json.dumps(arguments) + function['arguments'] = arguments split_arguments = split_json_objects(arguments) if len(split_arguments) <= 1: @@ -276,14 +293,14 @@ def get_citation_source_from_tool_result( - document: list of document contents - metadata: list of metadata objects with source, file_id, name fields - Returns a list of sources (usually one, but query_knowledge_files may return multiple). + Returns a list of sources (usually one, but query_knowledge_files/query_chat_files may return multiple). """ - _EXPECTS_LIST = {'search_web', 'query_knowledge_files'} + _EXPECTS_LIST = {'search_web', 'query_knowledge_files', 'query_chat_files'} _EXPECTS_DICT = {'view_knowledge_file', 'view_file'} try: try: - tool_result = json.loads(tool_result) + tool_result = JSONCodec.loads(tool_result) except (json.JSONDecodeError, TypeError): pass # keep tool_result as-is (e.g. fetch_url returns plain text) if isinstance(tool_result, dict) and 'error' in tool_result: @@ -367,7 +384,7 @@ def get_citation_source_from_tool_result( } ] - elif tool_name == 'query_knowledge_files': + elif tool_name in ('query_knowledge_files', 'query_chat_files'): chunks = tool_result # Group chunks by source for better citation display @@ -984,7 +1001,7 @@ async def process_tool_result( text = item.get('text', '') if isinstance(text, str): try: - text = json.loads(text) + text = JSONCodec.loads(text) except json.JSONDecodeError: pass tool_response.append(text) @@ -1012,7 +1029,7 @@ async def process_tool_result( text = resource.get('text', '') if isinstance(text, str) and text: try: - text = json.loads(text) + text = JSONCodec.loads(text) except json.JSONDecodeError: pass tool_response.append(text) @@ -1087,7 +1104,7 @@ async def terminal_event_handler( parsed = tool_result if isinstance(parsed, str): try: - parsed = json.loads(parsed) + parsed = JSONCodec.loads(parsed) except (json.JSONDecodeError, TypeError): pass if isinstance(parsed, dict) and parsed.get('exists') is False: @@ -1125,7 +1142,7 @@ async def chat_completion_tools_handler( content = None if hasattr(response, 'body_iterator'): async for chunk in response.body_iterator: - data = json.loads(chunk.decode('utf-8', 'replace')) + data = JSONCodec.loads(chunk.decode('utf-8', 'replace')) content = data['choices'][0]['message']['content'] # Cleanup any remaining background tasks if necessary @@ -1205,7 +1222,7 @@ async def chat_completion_tools_handler( if not content: raise Exception('No JSON object found in the response') - result = json.loads(content) + result = JSONCodec.loads(content) async def tool_call_handler(tool_call): nonlocal skip_files @@ -1374,7 +1391,7 @@ async def chat_web_search_handler(request: Request, form_data: dict, extra_param # user message as the search query. if isinstance(res, JSONResponse): try: - error_body = json.loads(res.body) + error_body = JSONCodec.loads(res.body) detail = error_body.get('detail', 'Query generation failed') except Exception: detail = 'Query generation failed' @@ -1390,7 +1407,7 @@ async def chat_web_search_handler(request: Request, form_data: dict, extra_param raise Exception('No JSON object found in the response') response = response[bracket_start:bracket_end] - queries = json.loads(response) + queries = JSONCodec.loads(response) queries = queries.get('queries', []) except Exception as e: queries = [response] @@ -1494,12 +1511,13 @@ async def chat_web_search_handler(request: Request, form_data: dict, extra_param except Exception as e: log.exception(e) + detail = e.detail if isinstance(e, HTTPException) else None await event_emitter( { 'type': 'status', 'data': { 'action': 'web_search', - 'description': 'An error occurred while searching the web', + 'description': (str(detail) if detail else 'An error occurred while searching the web'), 'queries': queries, 'done': True, 'error': True, @@ -1552,7 +1570,7 @@ async def add_file_context(messages: list, chat_id: str, user) -> list: """ Add file URLs to messages for native function calling. """ - if not chat_id or chat_id.startswith('local:') or chat_id.startswith('channel:'): + if not is_saved_chat_id(chat_id): return messages chat = await Chats.get_chat_by_id_and_user_id(chat_id, user.id) @@ -1563,7 +1581,11 @@ async def add_file_context(messages: list, chat_id: str, user) -> list: stored_messages = get_message_list(history.get('messages', {}), history.get('currentId')) def format_file_tag(file): - attrs = f'type="{file.get("type", "file")}" url="{file["url"]}"' + file_id = file.get('id') or file.get('url') + attrs = f'type="{file.get("type", "file")}"' + if file_id: + attrs += f' id="{file_id}"' + attrs += f' url="{file["url"]}"' if file.get('content_type'): attrs += f' content_type="{file["content_type"]}"' if file.get('name'): @@ -1608,7 +1630,7 @@ async def chat_image_generation_handler(request: Request, form_data: dict, extra if not chat_id or not isinstance(chat_id, str) or not __event_emitter__: return form_data - if chat_id.startswith('local:') or chat_id.startswith('channel:'): + if not is_saved_chat_id(chat_id): message_list = form_data.get('messages', []) else: chat = await Chats.get_chat_by_id_and_user_id(chat_id, user.id) @@ -1714,7 +1736,7 @@ async def chat_image_generation_handler(request: Request, form_data: dict, extra # Handle JSONResponse from error paths if isinstance(res, JSONResponse): try: - error_body = json.loads(res.body) + error_body = JSONCodec.loads(res.body) detail = error_body.get('detail', 'Image prompt generation failed') except Exception: detail = 'Image prompt generation failed' @@ -1730,7 +1752,7 @@ async def chat_image_generation_handler(request: Request, form_data: dict, extra raise Exception('No JSON object found in the response') response = response[bracket_start:bracket_end] - response = json.loads(response) + response = JSONCodec.loads(response) prompt = response.get('prompt', []) except Exception as e: prompt = user_message @@ -1834,7 +1856,7 @@ async def chat_completion_files_handler( raise Exception('No JSON object found in the response') queries_response = queries_response[bracket_start:bracket_end] - queries_response = json.loads(queries_response) + queries_response = JSONCodec.loads(queries_response) except Exception as e: queries_response = {'queries': [queries_response]} @@ -1945,7 +1967,7 @@ def apply_params_to_form_data(form_data, model): if isinstance(value, str): try: # Attempt to parse the string as JSON - custom_params[key] = json.loads(value) + custom_params[key] = JSONCodec.loads(value) except json.JSONDecodeError: # If it fails, keep the original string pass @@ -1967,7 +1989,7 @@ def apply_params_to_form_data(form_data, model): logit_bias = convert_logit_bias_input_to_json(params['logit_bias']) if logit_bias: - form_data['logit_bias'] = json.loads(logit_bias) + form_data['logit_bias'] = JSONCodec.loads(logit_bias) except Exception as e: log.exception(f'Error parsing logit_bias: {e}') @@ -2028,7 +2050,7 @@ async def load_messages_from_db(chat_id: str, message_id: str) -> Optional[list[ return None return [ - {k: v for k, v in msg.items() if k in ('id', 'role', 'content', 'output', 'files', 'contextSummary')} + {k: v for k, v in msg.items() if k in ('id', 'role', 'content', 'output', 'files', 'contextSummary', 'usage')} for msg in db_messages ] @@ -2069,6 +2091,7 @@ def process_messages_with_output( message['output'], raw=True, reasoning_format=reasoning_format, + flatten_tool_images=True, ) if output_messages: processed.extend(output_messages) @@ -2087,6 +2110,7 @@ def strip_compaction_fields(messages: list[dict]) -> list[dict]: clean = dict(message) clean.pop('contextSummary', None) clean.pop('context_summary', None) + clean.pop('usage', None) clean.pop('id', None) stripped.append(clean) return stripped @@ -2258,6 +2282,9 @@ async def process_chat_payload(request, form_data, user, metadata, model): form_data['model'] = selected_model_id metadata['selected_model_id'] = selected_model_id + # Captured before apply_params_to_form_data pops 'params'; feeds metadata['system_prompt'] below + model_system_prompt = (form_data.get('params') or {}).get('system') + form_data = apply_params_to_form_data(form_data, model) log.debug(f'form_data: {form_data}') @@ -2269,7 +2296,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): chat_id = metadata.get('chat_id') user_message_id = metadata.get('user_message_id') - if chat_id and user_message_id and not chat_id.startswith('local:') and not chat_id.startswith('channel:'): + if is_saved_chat_id(chat_id) and user_message_id: db_messages = await load_messages_from_db(chat_id, user_message_id) if db_messages: # Continue: frontend sends assistant_message_id when continuing @@ -2282,7 +2309,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): { k: v for k, v in assistant_message.items() - if k in ('id', 'role', 'content', 'output', 'files', 'contextSummary') + if k in ('id', 'role', 'content', 'output', 'files', 'contextSummary', 'usage') } ) @@ -2316,9 +2343,10 @@ async def process_chat_payload(request, form_data, user, metadata, model): if regeneration_prompt: form_data['messages'].append({'role': 'user', 'content': regeneration_prompt}) - if chat_id and user_message_id and not chat_id.startswith('local:') and not chat_id.startswith('channel:'): + if is_saved_chat_id(chat_id) and user_message_id: if getattr(request.state, 'direct', False) and hasattr(request.state, 'model'): compaction_models = { + **request.app.state.MODELS, request.state.model['id']: request.state.model, } else: @@ -2404,7 +2432,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): # Uses lightweight column query — only fetches folder_id, not the full chat JSON blob chat_id = metadata.get('chat_id', None) folder_id = None - if chat_id and user: + if user and is_saved_chat_id(chat_id): folder_id = await Chats.get_chat_folder_id(chat_id, user.id) # Fallback: use folder_id from metadata (temporary chats have no DB record) @@ -2483,11 +2511,11 @@ async def process_chat_payload(request, form_data, user, metadata, model): if ENABLE_PLUGINS: try: - filter_ids = await get_sorted_filter_ids(request, model, metadata.get('filter_ids', [])) - filter_functions = await Functions.get_functions_by_ids(filter_ids) + filter_functions = await get_filter_functions(request, model, metadata.get('filter_ids', [])) form_data, flags = await process_filter_functions( request=request, + filter_context=None, filter_functions=filter_functions, filter_type='inlet', form_data=form_data, @@ -2514,14 +2542,26 @@ async def process_chat_payload(request, form_data, user, metadata, model): form_data = await add_memory_context(request, form_data, user, model) if 'web_search' in features and features['web_search']: - # Skip forced RAG web search when native FC is enabled - model can use web_search tool - if metadata.get('params', {}).get('function_calling') == 'legacy': - form_data = await chat_web_search_handler(request, form_data, extra_params, user) + # features is client-supplied; re-check the permission the native FC path enforces. + if getattr(user, 'role', None) == 'admin' or await has_permission( + getattr(user, 'id', ''), + 'features.web_search', + await Config.get('user.permissions'), + ): + # Skip forced RAG web search when native FC is enabled - model can use web_search tool + if metadata.get('params', {}).get('function_calling') == 'legacy': + form_data = await chat_web_search_handler(request, form_data, extra_params, user) if 'image_generation' in features and features['image_generation']: - # Skip forced image generation when native FC is enabled - model can use generate_image tool - if metadata.get('params', {}).get('function_calling') == 'legacy': - form_data = await chat_image_generation_handler(request, form_data, extra_params, user) + # features is client-supplied; re-check the permission the direct /images routes enforce. + if getattr(user, 'role', None) == 'admin' or await has_permission( + getattr(user, 'id', ''), + 'features.image_generation', + await Config.get('user.permissions'), + ): + # Skip forced image generation when native FC is enabled - model can use generate_image tool + if metadata.get('params', {}).get('function_calling') == 'legacy': + form_data = await chat_image_generation_handler(request, form_data, extra_params, user) if 'code_interpreter' in features and features['code_interpreter']: engine = await Config.get('code_interpreter.engine', 'pyodide') @@ -2573,7 +2613,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): available_skills = [] view_skill_ids = [] chat = None - if metadata.get('chat_id') and not metadata['chat_id'].startswith(('local:', 'channel:')): + if is_saved_chat_id(metadata.get('chat_id')): chat = await Chats.get_chat_by_id(metadata['chat_id']) if chat and (chat.meta or {}).get('internal') is True and (chat.meta or {}).get('type') == 'note': @@ -2822,6 +2862,31 @@ async def process_chat_payload(request, form_data, user, metadata, model): # Add file context to user messages chat_id = metadata.get('chat_id') form_data['messages'] = await add_file_context(form_data.get('messages', []), chat_id, user) + + if (model.get('info', {}).get('meta', {}).get('builtinTools') or {}).get('knowledge', True): + from html import escape + + knowledge_tags = [] + for item in get_attached_knowledge(model, metadata): + if not item.get('id') or not item.get('type'): + continue + attrs = ( + f'type="{escape(str(item["type"]), quote=True)}" ' + f'id="{escape(str(item["id"]), quote=True)}"' + ) + if item.get('name'): + attrs += f' name="{escape(str(item["name"]), quote=True)}"' + if item.get('source'): + attrs += f' source="{escape(str(item["source"]), quote=True)}"' + knowledge_tags.append(f'') + + if knowledge_tags: + form_data['messages'] = add_or_update_system_message( + '\n' + '\n'.join(knowledge_tags) + '\n', + form_data['messages'], + append=True, + ) + builtin_tools = await get_builtin_tools( request, { @@ -2873,13 +2938,17 @@ async def process_chat_payload(request, form_data, user, metadata, model): # than a snapshot that already has the RAG template baked in. system_message = get_system_message(form_data['messages']) system_content = get_content_from_message(system_message) if system_message else '' - model_system_prompt = await resolve_system_prompt( - (form_data.get('params') or {}).get('system'), + resolved_model_system_prompt = await resolve_system_prompt( + model_system_prompt, metadata, user, ) - if model_system_prompt: - system_content = f'{model_system_prompt}\n{system_content}' if system_content else model_system_prompt + if resolved_model_system_prompt: + system_content = ( + f'{resolved_model_system_prompt}\n{system_content}' + if system_content + else resolved_model_system_prompt + ) metadata['system_prompt'] = system_content or None metadata['user_prompt'] = get_last_user_message(form_data['messages']) metadata['sources'] = sources[:] if sources else [] @@ -2963,7 +3032,7 @@ def get_response_data(response): if isinstance(response, JSONResponse): if isinstance(response.body, bytes): try: - response_data = json.loads(response.body.decode('utf-8', 'replace')) + response_data = JSONCodec.loads(response.body.decode('utf-8', 'replace')) except json.JSONDecodeError: response_data = {'error': {'detail': 'Invalid JSON response'}} else: @@ -3022,7 +3091,7 @@ def update_assistant_message_from_stream(assistant_message, raw): continue try: - data = json.loads(part) + data = JSONCodec.loads(part) except Exception: continue @@ -3137,11 +3206,7 @@ async def background_tasks_handler(ctx): message = None messages = [] - if ( - 'chat_id' in metadata - and not metadata.get('chat_id', '').startswith('local:') - and not metadata.get('chat_id', '').startswith('channel:') - ): + if is_saved_chat_id(metadata.get('chat_id')): messages_map = await Chats.get_messages_map_by_chat_id(metadata['chat_id']) if not messages_map: # Chat was deleted while the response was streaming — skip background tasks @@ -3214,7 +3279,7 @@ async def background_tasks_handler(ctx): ] try: - follow_ups = json.loads(follow_ups_string).get('follow_ups', []) + follow_ups = JSONCodec.loads(follow_ups_string).get('follow_ups', []) await event_emitter( { 'type': 'chat:message:follow_ups', @@ -3224,9 +3289,7 @@ async def background_tasks_handler(ctx): } ) - if not metadata.get('chat_id', '').startswith('local:') and not metadata.get( - 'chat_id', '' - ).startswith('channel:'): + if is_saved_chat_id(metadata.get('chat_id')): await Chats.upsert_message_to_chat_by_id_and_message_id( metadata['chat_id'], metadata['message_id'], @@ -3239,9 +3302,7 @@ async def background_tasks_handler(ctx): except Exception as e: pass - if not metadata.get('chat_id', '').startswith('local:') and not metadata.get('chat_id', '').startswith( - 'channel:' - ): # Only update titles and tags for non-temp chats + if is_saved_chat_id(metadata.get('chat_id')): # Only update titles and tags for saved chats if TASKS.TITLE_GENERATION in tasks: user_message = get_last_user_message(messages) if user_message and len(user_message) > 100: @@ -3276,7 +3337,7 @@ async def background_tasks_handler(ctx): title_string = title_string[title_string.find('{') : title_string.rfind('}') + 1] try: - title = json.loads(title_string).get('title', user_message) + title = JSONCodec.loads(title_string).get('title', user_message) except Exception as e: title = '' @@ -3328,7 +3389,7 @@ async def background_tasks_handler(ctx): tags_string = tags_string[tags_string.find('{') : tags_string.rfind('}') + 1] try: - tags = json.loads(tags_string).get('tags', []) + tags = JSONCodec.loads(tags_string).get('tags', []) await Chats.update_chat_tags_by_id(metadata['chat_id'], tags, user) await event_emitter( @@ -3377,11 +3438,11 @@ async def outlet_filter_handler(ctx): if not message_id: message_id = output_id('msg') - is_temp_chat = chat_id.startswith('local:') or chat_id.startswith('channel:') + is_unsaved_chat = not is_saved_chat_id(chat_id) try: messages_map = None - if is_temp_chat or not chat_id: + if is_unsaved_chat: form_messages = ctx.get('form_data', {}).get('messages', []) assistant_message = ctx.get('assistant_message', {}) @@ -3424,7 +3485,8 @@ async def outlet_filter_handler(ctx): 'content': m.get('content') or get_output_text(m.get('output')), 'info': m.get('info'), 'timestamp': m.get('timestamp'), - **({'output': m['output']} if m.get('output') else {}), + # Deepcopy so in-place filter mutations do not alias messages_map's baseline + **({'output': copy.deepcopy(m['output'])} if m.get('output') else {}), **({'usage': m['usage']} if m.get('usage') else {}), **({'sources': m['sources']} if m.get('sources') else {}), } @@ -3454,11 +3516,11 @@ async def outlet_filter_handler(ctx): } if ENABLE_PLUGINS: - filter_ids = await get_sorted_filter_ids(request, model, metadata.get('filter_ids', [])) - filter_functions = await Functions.get_functions_by_ids(filter_ids) + filter_functions = await get_filter_functions(request, model, metadata.get('filter_ids', [])) outlet_result, _ = await process_filter_functions( request=request, + filter_context=None, filter_functions=filter_functions, filter_type='outlet', form_data=outlet_data, @@ -3518,6 +3580,9 @@ async def non_streaming_chat_response_handler(response, ctx): if response_data is None: return response + chat_id = metadata.get('chat_id') or '' + save_to_chat = is_saved_chat_id(chat_id) + if event_emitter: try: if 'error' in response_data: @@ -3530,7 +3595,7 @@ async def non_streaming_chat_response_handler(response, ctx): log.error('Provider returned error (non-streaming): %s', error) - if not metadata.get('chat_id', '').startswith('channel:'): + if save_to_chat: await Chats.upsert_message_to_chat_by_id_and_message_id( metadata['chat_id'], metadata['message_id'], @@ -3546,7 +3611,7 @@ async def non_streaming_chat_response_handler(response, ctx): } ) - if 'selected_model_id' in response_data and not metadata.get('chat_id', '').startswith('channel:'): + if 'selected_model_id' in response_data and save_to_chat: await Chats.upsert_message_to_chat_by_id_and_message_id( metadata['chat_id'], metadata['message_id'], @@ -3569,11 +3634,7 @@ async def non_streaming_chat_response_handler(response, ctx): } ) - title = ( - await Chats.get_chat_title_by_id(metadata['chat_id']) - if not metadata.get('chat_id', '').startswith('channel:') - else '' - ) + title = await Chats.get_chat_title_by_id(metadata['chat_id']) if save_to_chat else '' # Use output from backend if provided (OR-compliant backends), # otherwise generate from response content @@ -3624,7 +3685,7 @@ async def non_streaming_chat_response_handler(response, ctx): # Save message in the database usage = normalize_usage(response_data.get('usage', {}) or {}) - if not metadata.get('chat_id', '').startswith('channel:'): + if save_to_chat: await Chats.upsert_message_to_chat_by_id_and_message_id( metadata['chat_id'], metadata['message_id'], @@ -3650,11 +3711,7 @@ async def non_streaming_chat_response_handler(response, ctx): except Exception as e: log.debug(f'Error occurred while processing request: {e}') chat_id = metadata.get('chat_id') - if ( - getattr(request.state, 'internal', False) is not True - and chat_id - and not chat_id.startswith(('channel:', 'local:')) - ): + if getattr(request.state, 'internal', False) is not True and chat_id and is_saved_chat_id(chat_id): webui_url = await Config.get('webui.url') await publish_event( request, @@ -3707,6 +3764,8 @@ async def streaming_chat_response_handler(response, ctx): event_emitter = ctx['event_emitter'] event_caller = ctx['event_caller'] + chat_id = metadata.get('chat_id') or '' + save_to_chat = is_saved_chat_id(chat_id) extra_params = { '__event_emitter__': event_emitter, @@ -3719,9 +3778,7 @@ async def streaming_chat_response_handler(response, ctx): } filter_functions = ( - await Functions.get_functions_by_ids( - await get_sorted_filter_ids(request, model, metadata.get('filter_ids', [])) - ) + await get_filter_functions(request, model, metadata.get('filter_ids', [])) if ENABLE_PLUGINS else [] ) @@ -3735,6 +3792,9 @@ async def streaming_chat_response_handler(response, ctx): # Handle as a background task async def response_handler(response, events): + filter_context = FilterContext() + tag_scan_positions = {} + def tag_output_handler(content_type, tags, output): """ Detect special tags (reasoning, solution, code_interpreter) in streaming @@ -3771,6 +3831,24 @@ async def streaming_chat_response_handler(response, ctx): if parts and parts[-1].get('type') == 'output_text': parts[-1]['text'] = text + def get_scanned_length(item, text): + item_id = item.get('id') + if not item_id: + return 0 + + scanned_length = tag_scan_positions.get((item_id, content_type), 0) + return scanned_length if scanned_length <= len(text) else 0 + + def save_scanned_length(item, text): + item_id = item.get('id') + if item_id: + tag_scan_positions[(item_id, content_type)] = len(text) + + def clear_scanned_length(item): + item_id = item.get('id') + if item_id: + tag_scan_positions.pop((item_id, content_type), None) + # Map content_type to output item type output_type_map = { 'reasoning': 'reasoning', @@ -3783,14 +3861,27 @@ async def streaming_chat_response_handler(response, ctx): if last_type == 'message': # Use the output item's own text for tag detection + item = output[-1] item_text = get_last_text(output) - for start_tag, end_tag in tags: - start_tag_pattern = rf'{re.escape(start_tag)}' - if start_tag.startswith('<') and start_tag.endswith('>'): - start_tag_pattern = rf'<{re.escape(start_tag[1:-1])}(\s.*?)?>' + scanned_length = get_scanned_length(item, item_text) + max_start_tag_length = max((len(start_tag) for start_tag, _ in tags), default=1) + search_start = max(0, scanned_length - max_start_tag_length + 1) - match = re.search(start_tag_pattern, item_text) + if scanned_length and any( + start_tag.startswith('<') and start_tag.endswith('>') for start_tag, _ in tags + ): + last_tag_boundary = max( + item_text.rfind('>', 0, scanned_length), + item_text.rfind('\n', 0, scanned_length), + ) + open_tag_start = item_text.rfind('<', 0, scanned_length) + if open_tag_start > last_tag_boundary: + search_start = min(search_start, open_tag_start) + + for start_tag, end_tag in tags: + match = re.compile(_start_tag_pattern(start_tag)).search(item_text, search_start) if match: + clear_scanned_length(item) try: attr_content = match.group(1) if match.group(1) else '' except Exception: @@ -3870,6 +3961,8 @@ async def streaming_chat_response_handler(response, ctx): end_flag = True break + else: + save_scanned_length(item, item_text) elif ( (last_type == 'reasoning' and content_type == 'reasoning') @@ -3880,8 +3973,6 @@ async def streaming_chat_response_handler(response, ctx): start_tag = item.get('start_tag', '') end_tag = item.get('end_tag', '') - end_tag_pattern = rf'{re.escape(end_tag)}' - # Get the block content from the item itself if last_type == 'reasoning': parts = item.get('content', []) @@ -3893,15 +3984,18 @@ async def streaming_chat_response_handler(response, ctx): else: block_content = get_last_text(output) - if re.search(end_tag_pattern, block_content): + scanned_length = get_scanned_length(item, block_content) + end_tag_search_start = max(0, scanned_length - max(len(end_tag), 1) + 1) + + if block_content.find(end_tag, end_tag_search_start) != -1: + clear_scanned_length(item) end_flag = True # Strip start and end tags from content - start_tag_pattern = rf'{re.escape(start_tag)}' - if start_tag.startswith('<') and start_tag.endswith('>'): - start_tag_pattern = rf'<{re.escape(start_tag[1:-1])}(\s.*?)?>' + start_tag_pattern = _start_tag_pattern(start_tag) block_content = re.sub(start_tag_pattern, '', block_content).strip() + end_tag_pattern = rf'{re.escape(end_tag)}' end_tag_regex = re.compile(end_tag_pattern, re.DOTALL) split_content = end_tag_regex.split(block_content, maxsplit=1) @@ -3955,10 +4049,16 @@ async def streaming_chat_response_handler(response, ctx): ], } ) + else: + save_scanned_length(item, block_content) return output, end_flag - message = await Chats.get_message_by_id_and_message_id(metadata['chat_id'], metadata['message_id']) + message = ( + await Chats.get_message_by_id_and_message_id(metadata['chat_id'], metadata['message_id']) + if save_to_chat + else None + ) tool_calls = [] @@ -4000,6 +4100,30 @@ async def streaming_chat_response_handler(response, ctx): def full_output(): return prior_output + output if prior_output else output + def get_message_error_content(error): + if isinstance(error, HTTPException): + error = error.detail + elif isinstance(error, dict): + error = error.get('detail', error) + else: + error = str(error) + + return error if isinstance(error, (str, dict)) else str(error) + + async def emit_message_error(error_content): + if save_to_chat: + await Chats.upsert_message_to_chat_by_id_and_message_id( + metadata['chat_id'], + metadata['message_id'], + {'error': {'content': error_content}}, + ) + await event_emitter( + { + 'type': 'chat:message:error', + 'data': {'error': {'content': error_content}}, + } + ) + reasoning_tags_param = metadata.get('params', {}).get('reasoning_tags') DETECT_REASONING_TAGS = reasoning_tags_param is not False @@ -4040,13 +4164,14 @@ async def streaming_chat_response_handler(response, ctx): ) # Save message in the database - await Chats.upsert_message_to_chat_by_id_and_message_id( - metadata['chat_id'], - metadata['message_id'], - { - **event, - }, - ) + if save_to_chat: + await Chats.upsert_message_to_chat_by_id_and_message_id( + metadata['chat_id'], + metadata['message_id'], + { + **event, + }, + ) async def stream_body_handler(response, form_data): nonlocal content_parts @@ -4096,12 +4221,14 @@ async def streaming_chat_response_handler(response, ctx): if delta_count >= delta_chunk_size: await flush_pending_delta_data(delta_chunk_size) + filter_extra_params = {'__body__': form_data, **extra_params} if filter_functions else None + async for line in response.body_iterator: line = line.decode('utf-8', 'replace') if isinstance(line, bytes) else line data = line # Skip empty lines - if not data.strip(): + if not data or data.isspace(): continue # "data:" is the prefix for each event @@ -4110,37 +4237,40 @@ async def streaming_chat_response_handler(response, ctx): # (without SSE `data:` prefix). Try to normalize these into standard # error events so frontend and DB paths still receive them. try: - raw_obj = json.loads(data) + raw_obj = JSONCodec.loads(data) raw_error = raw_obj.get('error') if isinstance(raw_obj, dict) else None if raw_error: - try: - await Chats.upsert_message_to_chat_by_id_and_message_id( - metadata['chat_id'], - metadata['message_id'], - { - 'error': {'content': raw_error}, - }, - ) - except Exception: - pass + if save_to_chat: + try: + await Chats.upsert_message_to_chat_by_id_and_message_id( + metadata['chat_id'], + metadata['message_id'], + { + 'error': {'content': raw_error}, + }, + ) + except Exception: + pass await event_emitter({'type': 'chat:completion', 'data': {'error': raw_error}}) except Exception: pass continue - # Remove the prefix - data = data[len('data:') :].strip() + # Remove the "data:" prefix + data = data[5:].strip() try: - data = json.loads(data) + data = JSONCodec.loads(data) - data, _ = await process_filter_functions( - request=request, - filter_functions=filter_functions, - filter_type='stream', - form_data=data, - extra_params={'__body__': form_data, **extra_params}, - ) + if filter_functions: + data, _ = await process_filter_functions( + request=request, + filter_context=filter_context, + filter_functions=filter_functions, + filter_type='stream', + form_data=data, + extra_params=filter_extra_params, + ) if data: if 'event' in data and not getattr(request.state, 'direct', False): @@ -4148,14 +4278,15 @@ async def streaming_chat_response_handler(response, ctx): if 'selected_model_id' in data: model_id = data['selected_model_id'] - await Chats.upsert_message_to_chat_by_id_and_message_id( - metadata['chat_id'], - metadata['message_id'], - { - 'selectedModelId': model_id, - }, - touch=False, - ) + if save_to_chat: + await Chats.upsert_message_to_chat_by_id_and_message_id( + metadata['chat_id'], + metadata['message_id'], + { + 'selectedModelId': model_id, + }, + touch=False, + ) await event_emitter( { 'type': 'chat:completion', @@ -4268,16 +4399,17 @@ async def streaming_chat_response_handler(response, ctx): error = data.get('error', {}) if error: log.error('Provider returned error (streaming): %s', error) - try: - await Chats.upsert_message_to_chat_by_id_and_message_id( - metadata['chat_id'], - metadata['message_id'], - { - 'error': {'content': error}, - }, - ) - except Exception: - pass + if save_to_chat: + try: + await Chats.upsert_message_to_chat_by_id_and_message_id( + metadata['chat_id'], + metadata['message_id'], + { + 'error': {'content': error}, + }, + ) + except Exception: + pass await event_emitter( { 'type': 'chat:completion', @@ -4340,7 +4472,13 @@ async def streaming_chat_response_handler(response, ctx): # Add the new tool call delta_tool_call.setdefault('function', {}) delta_tool_call['function'].setdefault('name', '') - delta_tool_call['function'].setdefault('arguments', '') + delta_arguments = delta_tool_call['function'].get('arguments') + if not isinstance(delta_arguments, str): + delta_tool_call['function']['arguments'] = ( + '' + if delta_arguments is None + else json.dumps(delta_arguments) + ) response_tool_calls.append(delta_tool_call) else: # Update the existing tool call @@ -4352,10 +4490,18 @@ async def streaming_chat_response_handler(response, ctx): if delta_name: current_response_tool_call['function']['name'] = delta_name - if delta_arguments: - current_response_tool_call['function']['arguments'] += ( - delta_arguments - ) + if delta_arguments is not None: + if not isinstance(delta_arguments, str): + delta_arguments = json.dumps(delta_arguments) + current_response_tool_call.setdefault('function', {}) + if not isinstance( + current_response_tool_call['function'].get('arguments'), + str, + ): + current_response_tool_call['function']['arguments'] = '' + current_response_tool_call['function'][ + 'arguments' + ] += delta_arguments # Emit pending tool calls in real-time if response_tool_calls: @@ -4380,16 +4526,23 @@ async def streaming_chat_response_handler(response, ctx): } delta_type = 'tool_call' - image_urls = await get_image_urls(delta.get('images', []), request, metadata, user) + delta_images = delta.get('images') + image_urls = ( + await get_image_urls(delta_images, request, metadata, user) + if delta_images + else [] + ) if image_urls: image_file_list = [{'type': 'image', 'url': url} for url in image_urls] - message_files = await Chats.add_message_files_by_id_and_message_id( - metadata['chat_id'], - metadata['message_id'], - image_file_list, - ) - if message_files is None: - message_files = image_file_list + message_files = image_file_list + if save_to_chat: + message_files = await Chats.add_message_files_by_id_and_message_id( + metadata['chat_id'], + metadata['message_id'], + image_file_list, + ) + if message_files is None: + message_files = image_file_list await event_emitter( { @@ -4406,13 +4559,35 @@ async def streaming_chat_response_handler(response, ctx): or delta.get('thinking') ) reasoning_details = delta.get('reasoning_details') - if reasoning_content or reasoning_details: - reasoning_item = ( - next( - (item for item in reversed(output) if item.get('type') == 'reasoning'), - None, + reasoning_detail_items = ( + [item for item in reasoning_details if isinstance(item, dict)] + if isinstance(reasoning_details, list) + else [reasoning_details] + if isinstance(reasoning_details, dict) + else [] + ) + existing_reasoning_item = next( + (item for item in reversed(output) if item.get('type') == 'reasoning'), + None, + ) + message_index = next( + (i for i, item in enumerate(output) if item.get('type') == 'message'), + None, + ) + if reasoning_content or ( + reasoning_detail_items + and ( + existing_reasoning_item + or any( + item.get('text') or item.get('summary') or item.get('data') + for item in reasoning_detail_items ) - if reasoning_details and not reasoning_content + ) + ): + reasoning_item = ( + existing_reasoning_item + if (reasoning_detail_items and not reasoning_content) + or message_index is not None else None ) @@ -4429,7 +4604,13 @@ async def streaming_chat_response_handler(response, ctx): 'summary': None, 'started_at': time.time(), } - output.append(reasoning_item) + if message_index is not None: + reasoning_item['ended_at'] = time.time() + reasoning_item['duration'] = 0 + reasoning_item['status'] = 'completed' + output.insert(message_index, reasoning_item) + else: + output.append(reasoning_item) else: reasoning_item = output[-1] @@ -4451,10 +4632,10 @@ async def streaming_chat_response_handler(response, ctx): } delta_type = 'content' - if reasoning_details: + if reasoning_detail_items: merge_streamed_reasoning_details( reasoning_item.setdefault('reasoning_details', []), - reasoning_details, + reasoning_detail_items, ) data = { 'output': full_output(), @@ -4605,9 +4786,7 @@ async def streaming_chat_response_handler(response, ctx): if end: break - if ENABLE_REALTIME_CHAT_SAVE and not metadata.get('chat_id', '').startswith( - 'channel:' - ): + if ENABLE_REALTIME_CHAT_SAVE and save_to_chat: current_output = full_output() # Save message in the database await Chats.upsert_message_to_chat_by_id_and_message_id( @@ -4783,7 +4962,7 @@ async def streaming_chat_response_handler(response, ctx): params = {} if tool_args and tool_args.strip(): try: - params = json.loads(tool_args) + params = JSONCodec.loads(tool_args) except Exception: try: params = ast.literal_eval(tool_args) @@ -4892,6 +5071,7 @@ async def streaming_chat_response_handler(response, ctx): 'view_file', 'view_knowledge_file', 'query_knowledge_files', + 'query_chat_files', ] and tool_result ): @@ -5063,7 +5243,10 @@ async def streaming_chat_response_handler(response, ctx): new_form_data['previous_response_id'] = last_response_id else: tool_messages = convert_output_to_messages( - output, raw=True, reasoning_format=get_reasoning_format(model) + output, + raw=True, + reasoning_format=get_reasoning_format(model), + flatten_tool_images=True, ) # Chat Completions providers don't support multimodal @@ -5131,7 +5314,9 @@ async def streaming_chat_response_handler(response, ctx): else: break except Exception as e: - log.debug(e) + error_content = get_message_error_content(e) + log.exception('Tool-call continuation failed: %s', error_content) + await emit_message_error(error_content) break if ( @@ -5141,18 +5326,7 @@ async def streaming_chat_response_handler(response, ctx): ): log.warning('Tool-call iteration limit reached (%s)', max_tool_call_iterations) error_content = f'Tool-call limit reached ({max_tool_call_iterations} iterations).' - if not metadata.get('chat_id', '').startswith('channel:'): - await Chats.upsert_message_to_chat_by_id_and_message_id( - metadata['chat_id'], - metadata['message_id'], - {'error': {'content': error_content}}, - ) - await event_emitter( - { - 'type': 'chat:message:error', - 'data': {'error': {'content': error_content}}, - } - ) + await emit_message_error(error_content) if DETECT_CODE_INTERPRETER: MAX_RETRIES = 5 @@ -5304,7 +5478,10 @@ async def streaming_chat_response_handler(response, ctx): 'messages': [ *form_data['messages'], *convert_output_to_messages( - output, raw=True, reasoning_format=get_reasoning_format(model) + output, + raw=True, + reasoning_format=get_reasoning_format(model), + flatten_tool_images=True, ), ], } @@ -5321,7 +5498,9 @@ async def streaming_chat_response_handler(response, ctx): else: break except Exception as e: - log.debug(e) + error_content = get_message_error_content(e) + log.exception('Code interpreter continuation failed: %s', error_content) + await emit_message_error(error_content) break # Mark all in-progress items as completed @@ -5329,11 +5508,7 @@ async def streaming_chat_response_handler(response, ctx): if item.get('status') == 'in_progress': item['status'] = 'completed' - title = ( - await Chats.get_chat_title_by_id(metadata['chat_id']) - if not metadata.get('chat_id', '').startswith('channel:') - else '' - ) + title = await Chats.get_chat_title_by_id(metadata['chat_id']) if save_to_chat else '' data = { 'done': True, 'output': output, @@ -5341,7 +5516,7 @@ async def streaming_chat_response_handler(response, ctx): **({'usage': usage} if usage else {}), } - if not metadata.get('chat_id', '').startswith('channel:'): + if save_to_chat: if not ENABLE_REALTIME_CHAT_SAVE: # Save message in the database await Chats.upsert_message_to_chat_by_id_and_message_id( @@ -5376,6 +5551,7 @@ async def streaming_chat_response_handler(response, ctx): ) ctx['assistant_message'] = { + 'content': ''.join(content_parts) or get_output_text(output), 'output': output, **({'usage': usage} if usage else {}), } @@ -5396,7 +5572,7 @@ async def streaming_chat_response_handler(response, ctx): async def save_cancelled_state(): await event_emitter({'type': 'chat:tasks:cancel'}) - if not metadata.get('chat_id', '').startswith('channel:'): + if save_to_chat: if not ENABLE_REALTIME_CHAT_SAVE: await Chats.upsert_message_to_chat_by_id_and_message_id( metadata['chat_id'], @@ -5432,6 +5608,7 @@ async def streaming_chat_response_handler(response, ctx): return f'data: {item}\n\n' assistant_message = {} + filter_context = FilterContext() has_api_outlet_filters = ENABLE_API_OUTLET_FILTERS and bool(filter_functions) if ENABLE_API_OUTLET_FILTERS and not has_api_outlet_filters: try: @@ -5446,6 +5623,7 @@ async def streaming_chat_response_handler(response, ctx): for event in events: event, _ = await process_filter_functions( request=request, + filter_context=filter_context, filter_functions=filter_functions, filter_type='stream', form_data=event, @@ -5453,11 +5631,12 @@ async def streaming_chat_response_handler(response, ctx): ) if event: - yield wrap_item(json.dumps(event)) + yield wrap_item(JSONCodec.dumps(event)) async for data in original_generator: data, _ = await process_filter_functions( request=request, + filter_context=filter_context, filter_functions=filter_functions, filter_type='stream', form_data=data, diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py index cff3ad6e40..8b867ff2d3 100644 --- a/backend/open_webui/utils/misc.py +++ b/backend/open_webui/utils/misc.py @@ -194,9 +194,7 @@ def get_output_text(output: list | None) -> str: continue text = ''.join( - str(part.get('text')) - for part in parts - if isinstance(part, dict) and part.get('text') is not None + str(part.get('text')) for part in parts if isinstance(part, dict) and part.get('text') is not None ) if text.strip(): texts.append(text) @@ -260,6 +258,7 @@ def convert_output_to_messages( output: list, raw: bool = False, reasoning_format: str | None = None, + flatten_tool_images: bool = False, ) -> list[dict]: """ Convert OR-aligned output items to OpenAI Chat Completion-format messages. @@ -278,6 +277,8 @@ def convert_output_to_messages( (for Ollama, which expects reasoning as tagged content). - ``'reasoning_content'``: set as ``reasoning_content`` top-level field (for llama.cpp, which routes it via the chat template). + flatten_tool_images: Move tool output images into a following user + message for Chat Completions providers. """ if not output or not isinstance(output, list): return [] @@ -287,6 +288,10 @@ def convert_output_to_messages( pending_content = [] pending_reasoning = [] # Only populated when reasoning_format == 'reasoning_content' pending_reasoning_details = [] + pending_tool_image_urls = [] + function_call_ids = { + item.get('call_id') for item in output if item.get('type') == 'function_call' and item.get('call_id') + } def flush_pending(): nonlocal pending_content, pending_tool_calls, pending_reasoning, pending_reasoning_details @@ -311,8 +316,29 @@ def convert_output_to_messages( pending_reasoning = [] pending_reasoning_details = [] + def flush_tool_images(): + nonlocal pending_tool_image_urls + if not pending_tool_image_urls: + return + + messages.append( + { + 'role': 'user', + 'content': [ + { + 'type': 'text', + 'text': 'Here are the images from the tool results above. Please analyze them.', + }, + *[{'type': 'image_url', 'image_url': {'url': url}} for url in pending_tool_image_urls], + ], + } + ) + pending_tool_image_urls = [] + for item in output: item_type = item.get('type', '') + if item_type != 'function_call_output': + flush_tool_images() if item_type == 'message': # Extract text from output_text content parts @@ -358,8 +384,17 @@ def convert_output_to_messages( if url: image_urls.append(url) - if image_urls: - # Multimodal tool content with image(s) + if flatten_tool_images: + messages.append( + { + 'role': 'tool', + 'tool_call_id': item.get('call_id', ''), + 'content': content, + } + ) + if item.get('call_id') in function_call_ids: + pending_tool_image_urls.extend(image_urls) + elif image_urls: messages.append( { 'role': 'tool', @@ -431,6 +466,7 @@ def convert_output_to_messages( pass # Flush remaining content/tool_calls + flush_tool_images() flush_pending() return reconcile_tool_pairs(messages) @@ -627,9 +663,9 @@ def strip_empty_content_blocks(messages: list[dict]) -> list[dict]: return messages -def openai_chat_message_template(model: str): +def openai_chat_message_template(model: str, message_id: str | None = None): return { - 'id': f'{model}-{str(uuid.uuid4())}', + 'id': message_id if message_id else f'{model}-{str(uuid.uuid4())}', 'created': int(time.time()), 'model': model, 'choices': [{'index': 0, 'logprobs': None, 'finish_reason': None}], @@ -642,8 +678,9 @@ def openai_chat_chunk_message_template( reasoning_content: str | None = None, tool_calls: list[dict | None] = None, usage: dict | None = None, + message_id: str | None = None, ) -> dict: - template = openai_chat_message_template(model) + template = openai_chat_message_template(model, message_id) template['object'] = 'chat.completion.chunk' template['choices'][0]['index'] = 0 diff --git a/backend/open_webui/utils/model_ids.py b/backend/open_webui/utils/model_ids.py new file mode 100644 index 0000000000..c28c8b532d --- /dev/null +++ b/backend/open_webui/utils/model_ids.py @@ -0,0 +1,4 @@ +def strip_provider_model_prefix(model_id: str, prefix_id: str | None) -> str: + if prefix_id and model_id.startswith(f'{prefix_id}.'): + return model_id[len(f'{prefix_id}.') :] + return model_id diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index a5b2261b14..79ea1030a2 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -428,7 +428,7 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) return models -async def check_model_access(user, model, db=None): +async def check_model_access(user, model, model_info=None, db=None): if model.get('arena'): meta = model.get('info', {}).get('meta', {}) access_grants = meta.get('access_grants', []) @@ -440,23 +440,35 @@ async def check_model_access(user, model, db=None): ): raise Exception('Model not found') else: - model_info = await Models.get_model_by_id(model.get('id'), db=db) + # Callers that already fetched the row (chat completion entry) pass it in + if model_info is None or model_info.id != model.get('id'): + model_info = await Models.get_model_by_id(model.get('id'), db=db) if not model_info: raise Exception('Model not found') - elif not ( + + # One group-membership fetch shared by the direct check and every + # base-model hop; skipped when no check below needs it. + user_group_ids = None + if user.id != model_info.user_id or model_info.base_model_id: + user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)} + + if not ( user.id == model_info.user_id or await AccessGrants.has_access( user_id=user.id, resource_type='model', resource_id=model_info.id, permission='read', + user_group_ids=user_group_ids, db=db, ) ): raise Exception('Model not found') # Enforce access on chained base models - if not await has_base_model_access(user.id, model_info, user_role=user.role, db=db): + if not await has_base_model_access( + user.id, model_info, user_role=user.role, user_group_ids=user_group_ids, db=db + ): raise Exception('Model not found') diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 63c72eeac3..0cbfcb2ebf 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -15,6 +15,7 @@ from types import SimpleNamespace from typing import Literal, Optional import aiohttp +import jwt from authlib.integrations.starlette_client import OAuth from authlib.oauth2.rfc6749.errors import OAuth2Error from authlib.oidc.core import UserInfo @@ -35,6 +36,7 @@ from mcp.shared.auth import ( from open_webui.config import ( DEFAULT_USER_ROLE, ENABLE_OAUTH_GROUP_CREATION, + ENABLE_OAUTH, ENABLE_OAUTH_GROUP_MANAGEMENT, ENABLE_OAUTH_ROLE_MANAGEMENT, ENABLE_OAUTH_SIGNUP, @@ -82,7 +84,7 @@ from open_webui.models.config import Config from open_webui.models.groups import GroupForm, GroupModel, Groups, GroupUpdateForm from open_webui.models.oauth_sessions import OAuthSessions from open_webui.models.users import Users -from open_webui.retrieval.web.utils import validate_url +from open_webui.retrieval.web.utils import get_ssrf_safe_session, validate_url from open_webui.utils.auth import create_token, get_password_hash from open_webui.utils.groups import apply_default_group_assignment from open_webui.utils.misc import parse_duration @@ -120,6 +122,7 @@ OAUTH_RESOURCE_PARAMETER_MODES = {'auto', 'include', 'omit'} OAUTH_RUNTIME_CONFIG = { 'DEFAULT_USER_ROLE': ('ui.default_user_role', DEFAULT_USER_ROLE), + 'ENABLE_OAUTH': ('oauth.enable', ENABLE_OAUTH), 'ENABLE_OAUTH_SIGNUP': ('oauth.enable_signup', ENABLE_OAUTH_SIGNUP), 'OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE': ( 'oauth.refresh_token.include_scope', @@ -187,6 +190,7 @@ async def get_oauth_runtime_config() -> SimpleNamespace: # Conservative default when the provider omits both expires_in and expires_at. # Matches the value recommended by Authlib's compliance_fix documentation. DEFAULT_TOKEN_EXPIRY_SECONDS = 3600 +NON_EXPIRING_TOKEN_EXPIRES_AT = 253402300799 # 9999-12-31 23:59:59 UTC # Apereo CAS includes client_id in ID token JWS headers; Authlib 1.7/joserfc @@ -203,27 +207,43 @@ def _normalize_token_expiry(token: dict) -> dict: Resolution order: 1. If *expires_at* is already present and non-None, trust it. 2. Else if *expires_in* is present and non-None, compute *expires_at*. - 3. Otherwise fall back to ``DEFAULT_TOKEN_EXPIRY_SECONDS`` and log a - warning so operators can identify providers that omit expiration. + 3. Else if a *refresh_token* is present, fall back to + ``DEFAULT_TOKEN_EXPIRY_SECONDS`` and log a warning so operators can + identify providers that omit expiration. + 4. Otherwise treat the token as non-expiring; there is no refresh path to + recover from a fabricated short expiry. Also stamps *issued_at* for auditing. """ token['issued_at'] = datetime.now().timestamp() if token.get('expires_at') is not None: - token['expires_at'] = int(token['expires_at']) - return token + expires_at = int(token['expires_at']) + elif token.get('expires_in') is not None: + expires_at = int(datetime.now().timestamp() + token['expires_in']) + elif token.get('refresh_token'): + log.warning( + "OAuth token response missing both 'expires_in' and 'expires_at'; " + f'defaulting to {DEFAULT_TOKEN_EXPIRY_SECONDS}s from now' + ) + expires_at = int(datetime.now().timestamp() + DEFAULT_TOKEN_EXPIRY_SECONDS) + else: + log.info( + "OAuth token response missing 'expires_in', 'expires_at' and 'refresh_token'; treating token as non-expiring" + ) + expires_at = NON_EXPIRING_TOKEN_EXPIRES_AT - if token.get('expires_in') is not None: - token['expires_at'] = int(datetime.now().timestamp() + token['expires_in']) - return token + id_token = token.get('id_token') + if id_token: + # Cap at the id_token expiry so pipes and tools never receive an expired JWT + try: + exp = jwt.decode(id_token, options={'verify_signature': False}).get('exp') + if exp is not None: + expires_at = min(expires_at, int(exp)) + except Exception as e: + log.debug(f'Could not read exp from id_token: {e}') - # Neither field present — conservative fallback - log.warning( - "OAuth token response missing both 'expires_in' and 'expires_at'; " - f'defaulting to {DEFAULT_TOKEN_EXPIRY_SECONDS}s from now' - ) - token['expires_at'] = int(datetime.now().timestamp() + DEFAULT_TOKEN_EXPIRY_SECONDS) + token['expires_at'] = expires_at return token @@ -536,6 +556,20 @@ async def get_oauth_client_info_with_dynamic_client_registration( log.error(f'Error parsing OAuth metadata from {url}: {e}') continue + # Fail fast if authorization server metadata discovery did not resolve an + # authorization endpoint. Otherwise registration can still "succeed" (via + # the /register fallback below) while issuer/server_metadata stay unset, + # which later crashes at authorize time with authlib's + # RuntimeError: Missing "authorize_url" value. (#26647) + if oauth_server_metadata is None or not oauth_server_metadata.authorization_endpoint: + log.error(f'OAuth authorization server metadata discovery failed for {oauth_server_url}') + raise Exception( + 'Could not discover the OAuth authorization server metadata ' + f'(authorization_endpoint) for {oauth_server_url}. The MCP server must ' + 'expose RFC 8414 / RFC 9728 discovery documents so Open WebUI can ' + 'resolve where to send users to authorize.' + ) + registration_url = None if oauth_server_metadata and oauth_server_metadata.registration_endpoint: registration_url = str(oauth_server_metadata.registration_endpoint) @@ -802,6 +836,17 @@ class OAuthClientManager: 'server_metadata_url': (oauth_client_info.issuer if oauth_client_info.issuer else None), } + # Defense-in-depth: when the server metadata is already known, pass the + # authorization/token endpoints explicitly so authlib does not rely solely + # on refetching server_metadata_url (which may be missing/unreachable) to + # resolve them. Prevents RuntimeError: Missing "authorize_url". (#26647) + server_metadata = oauth_client_info.server_metadata + if server_metadata is not None: + if getattr(server_metadata, 'authorization_endpoint', None): + kwargs['authorize_url'] = str(server_metadata.authorization_endpoint) + if getattr(server_metadata, 'token_endpoint', None): + kwargs['access_token_url'] = str(server_metadata.token_endpoint) + # Default to S256 for OAuth 2.1 (PKCE is mandatory per RFC 9700) kwargs['code_challenge_method'] = 'S256' @@ -1138,7 +1183,22 @@ class OAuthClientManager: redirect_uri_str = str(redirect_uri) if redirect_uri else None # Pass explicit scope/resource parameters for providers that require them. kwargs = build_oauth_request_params(client_info) - return await client.authorize_redirect(request, redirect_uri_str, **kwargs) + try: + return await client.authorize_redirect(request, redirect_uri_str, **kwargs) + except RuntimeError as e: + # authlib raises RuntimeError('Missing "authorize_url" value') when the + # authorization endpoint could not be resolved from server metadata. + # Surface a clear 400 instead of an uncaught 500 for clients that were + # registered before discovery was validated. (#26647) + log.error(f'OAuth authorize failed for client {client_id}: {e}') + raise HTTPException( + status_code=400, + detail=( + 'OAuth authorization endpoint could not be resolved for this ' + 'client. Re-register the MCP server; its OAuth discovery ' + 'documents may be missing or unreachable.' + ), + ) async def handle_callback(self, request, client_id: str, user_id: str, response): client = await self.get_client(client_id) @@ -1641,8 +1701,8 @@ class OAuthManager: get_kwargs['headers'] = { 'Authorization': f'Bearer {access_token}', } - async with aiohttp.ClientSession(trust_env=True) as session: - # allow_redirects=False prevents redirect-based SSRF: validate_url() only vetted the initial URL (CVE-2026-45401 cohort). + # get_ssrf_safe_session pins the connect-time IP (defeats DNS rebinding); allow_redirects=False keeps validate_url's vet authoritative. + async with get_ssrf_safe_session() as session: async with session.get( picture_url, **get_kwargs, @@ -1670,6 +1730,8 @@ class OAuthManager: async def handle_login(self, request, provider): auth_config = await get_oauth_runtime_config() + if not auth_config.ENABLE_OAUTH: + raise HTTPException(404) if provider not in OAUTH_PROVIDERS: raise HTTPException(404) # If the provider has a custom redirect URL, use that, otherwise automatically generate one @@ -1690,6 +1752,8 @@ class OAuthManager: async def handle_callback(self, request, provider, response, db=None): auth_config = await get_oauth_runtime_config() + if not auth_config.ENABLE_OAUTH: + raise HTTPException(404) if provider not in OAUTH_PROVIDERS: raise HTTPException(404) diff --git a/backend/open_webui/utils/payload.py b/backend/open_webui/utils/payload.py index 89568c3a63..e47e72b94f 100644 --- a/backend/open_webui/utils/payload.py +++ b/backend/open_webui/utils/payload.py @@ -1,4 +1,3 @@ -import copy import json from typing import Callable, Optional @@ -307,9 +306,10 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict: Returns: dict: A modified payload compatible with the Ollama API. """ - # Shallow copy metadata separately (may contain non-picklable objects) + # Only the top-level dict and the nested options dict are mutated below, so + # shallow copies suffice; deepcopy walked the entire message tree per call. metadata = openai_payload.get('metadata') - openai_payload = copy.deepcopy({k: v for k, v in openai_payload.items() if k != 'metadata'}) + openai_payload = {k: v for k, v in openai_payload.items() if k != 'metadata'} if metadata is not None: openai_payload['metadata'] = dict(metadata) ollama_payload = {} @@ -327,8 +327,9 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict: # If there are advanced parameters in the payload, format them in Ollama's options field if openai_payload.get('options'): - ollama_payload['options'] = openai_payload['options'] - ollama_options = openai_payload['options'] + # Copied before key deletions below so the caller's options stay intact + ollama_options = dict(openai_payload['options']) + ollama_payload['options'] = ollama_options def parse_json(value: str) -> dict: """ diff --git a/backend/open_webui/utils/redis.py b/backend/open_webui/utils/redis.py index bee7f633b2..90d81abb26 100644 --- a/backend/open_webui/utils/redis.py +++ b/backend/open_webui/utils/redis.py @@ -23,6 +23,7 @@ from open_webui.env import ( REDIS_SENTINEL_PORT, REDIS_SOCKET_CONNECT_TIMEOUT, REDIS_SOCKET_KEEPALIVE, + REDIS_SOCKET_TIMEOUT, REDIS_URL, ) @@ -257,6 +258,8 @@ def _socket_options() -> dict[str, Any]: opts: dict[str, Any] = {} if REDIS_SOCKET_CONNECT_TIMEOUT is not None: opts['socket_connect_timeout'] = REDIS_SOCKET_CONNECT_TIMEOUT + if REDIS_SOCKET_TIMEOUT: + opts['socket_timeout'] = REDIS_SOCKET_TIMEOUT if REDIS_SOCKET_KEEPALIVE: opts['socket_keepalive'] = True if REDIS_HEALTH_CHECK_INTERVAL: @@ -303,6 +306,7 @@ def get_redis_connection( cache_key = ( redis_url, tuple(redis_sentinels) if redis_sentinels else (), + redis_cluster, async_mode, decode_responses, ) diff --git a/backend/open_webui/utils/response.py b/backend/open_webui/utils/response.py index de3ede0a07..29c021487b 100644 --- a/backend/open_webui/utils/response.py +++ b/backend/open_webui/utils/response.py @@ -2,6 +2,7 @@ import json from numbers import Number from uuid import uuid4 +from open_webui.utils.json_codec import JSONCodec from open_webui.utils.misc import ( openai_chat_chunk_message_template, openai_chat_completion_message_template, @@ -55,8 +56,6 @@ USAGE_TOKEN_KEYS = { 'input_tokens', 'output_tokens', 'total_tokens', - 'prompt_tokens', - 'completion_tokens', } USAGE_COST_KEYS = { @@ -68,6 +67,8 @@ USAGE_COST_KEYS = { 'completion_cost', } +USAGE_SUMMABLE_KEYS = USAGE_TOKEN_KEYS | USAGE_COST_KEYS + USAGE_DETAIL_KEYS = { 'prompt_tokens_details', 'completion_tokens_details', @@ -105,7 +106,7 @@ def merge_usage(current: dict | None, incoming: dict | None) -> dict: """ Merge usage payloads from multiple model calls into one cumulative usage dict. - Token fields are additive; non-numeric metadata keeps the latest provider value. + Canonical token fields are additive; provider aliases keep the latest value. """ current_usage = normalize_usage(current or {}) if current else {} incoming_usage = normalize_usage(incoming or {}) if incoming else {} @@ -117,7 +118,7 @@ def merge_usage(current: dict | None, incoming: dict | None) -> dict: result = {**current_usage, **incoming_usage} - for key in USAGE_TOKEN_KEYS | USAGE_COST_KEYS: + for key in USAGE_SUMMABLE_KEYS: if key in current_usage or key in incoming_usage: current_value = current_usage.get(key, 0) incoming_value = incoming_usage.get(key, 0) @@ -133,6 +134,17 @@ def merge_usage(current: dict | None, incoming: dict | None) -> dict: incoming_usage.get(key) if isinstance(incoming_usage.get(key), dict) else {}, ) + result['prompt_tokens'] = ( + incoming_usage.get('prompt_tokens') + or incoming_usage.get('input_tokens') + or current_usage.get('prompt_tokens', 0) + ) + result['completion_tokens'] = ( + incoming_usage.get('completion_tokens') + or incoming_usage.get('output_tokens') + or current_usage.get('completion_tokens', 0) + ) + return result @@ -226,12 +238,13 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response) completion_id = f'chatcmpl-{str(uuid4())}' first = True async for data in ollama_streaming_response.body_iterator: - data = json.loads(data) + data = JSONCodec.loads(data) model = data.get('model', 'ollama') - message_content = data.get('message', {}).get('content', None) - reasoning_content = data.get('message', {}).get('thinking', None) - tool_calls = data.get('message', {}).get('tool_calls', None) + message = data.get('message') or {} + message_content = message.get('content', None) + reasoning_content = message.get('thinking', None) + tool_calls = message.get('tool_calls', None) openai_tool_calls = None if tool_calls: @@ -244,8 +257,9 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response) if done: usage = convert_ollama_usage_to_openai(data) - data = openai_chat_chunk_message_template(model, message_content, reasoning_content, openai_tool_calls, usage) - data['id'] = completion_id + data = openai_chat_chunk_message_template( + model, message_content, reasoning_content, openai_tool_calls, usage, message_id=completion_id + ) # First chunk must carry delta.role (OpenAI spec). if first: @@ -255,7 +269,7 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response) if done and has_tool_calls: data['choices'][0]['finish_reason'] = 'tool_calls' - line = f'data: {json.dumps(data)}\n\n' + line = f'data: {JSONCodec.dumps(data)}\n\n' yield line yield 'data: [DONE]\n\n' diff --git a/backend/open_webui/utils/session_pool.py b/backend/open_webui/utils/session_pool.py index 90ca728bd9..fb66c3e2cf 100644 --- a/backend/open_webui/utils/session_pool.py +++ b/backend/open_webui/utils/session_pool.py @@ -28,6 +28,7 @@ from typing import Optional import aiohttp from open_webui.env import ( + AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT, AIOHTTP_CLIENT_TIMEOUT, AIOHTTP_POOL_CONNECTIONS, AIOHTTP_POOL_CONNECTIONS_PER_HOST, @@ -38,6 +39,16 @@ log = logging.getLogger(__name__) _session: Optional[aiohttp.ClientSession] = None +_CLIENT_TIMEOUT = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) +_CLIENT_STREAM_TIMEOUT = aiohttp.ClientTimeout( + total=AIOHTTP_CLIENT_TIMEOUT, + sock_read=AIOHTTP_CLIENT_STREAM_IDLE_TIMEOUT, +) + + +def get_client_timeout(stream: bool = False) -> aiohttp.ClientTimeout: + return _CLIENT_STREAM_TIMEOUT if stream else _CLIENT_TIMEOUT + async def get_session() -> aiohttp.ClientSession: """Return the shared aiohttp ClientSession, creating it lazily.""" @@ -56,7 +67,7 @@ async def get_session() -> aiohttp.ClientSession: else: connector_kwargs['limit_per_host'] = 0 # aiohttp: 0 = unlimited connector = aiohttp.TCPConnector(**connector_kwargs) - timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) + timeout = get_client_timeout() _session = aiohttp.ClientSession( connector=connector, timeout=timeout, @@ -104,14 +115,23 @@ async def cleanup_response( await result -async def stream_wrapper(response, session=None, content_handler=None): +async def stream_wrapper(response, session=None, content_handler=None, passthrough=False): """Wrap a stream to ensure cleanup happens even if streaming is interrupted. This is more reliable than BackgroundTask which may not run if the client disconnects. When using the shared pool, ``session`` should be ``None``. + + ``passthrough=True`` yields raw network chunks (iter_any) instead of + lines: byte-identical output without a buffer scan, slice and copy per + line. Only for streams no internal consumer parses line-by-line. """ try: - stream = content_handler(response.content) if content_handler else response.content + if content_handler: + stream = content_handler(response.content) + elif passthrough: + stream = response.content.iter_any() + else: + stream = response.content async for chunk in stream: yield chunk finally: diff --git a/backend/open_webui/utils/timers.py b/backend/open_webui/utils/timers.py index 25d98f17be..5500daa21a 100644 --- a/backend/open_webui/utils/timers.py +++ b/backend/open_webui/utils/timers.py @@ -199,10 +199,14 @@ async def claim_due_timers(now_ns: int, limit: int = 10) -> list[tuple[str, str] return claimed -async def cancel_timers_for_chat(parent_chat_id: str, event: Literal['chat.read', 'chat.user_message']) -> None: +async def cancel_timers_for_chat( + parent_chat_id: str, event: Literal['chat.read', 'chat.user_message'], user_id: str +) -> None: + """Owner-scoped: without the user filter, reading a chat cancels every user's timers on it.""" async with get_async_db() as db: result = await db.execute( select(Chat) + .where(Chat.user_id == user_id) .where(Chat.meta['internal'].as_boolean().is_(True)) .where(Chat.meta['type'].as_string() == 'timer') .where(Chat.meta['parent_chat_id'].as_string() == parent_chat_id) diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index c78b315304..3f7d2aa094 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -8,7 +8,7 @@ import json import logging import os import re -from functools import partial, update_wrapper +from functools import cache, partial, update_wrapper from typing import ( Any, Awaitable, @@ -46,6 +46,7 @@ from open_webui.models.config import Config from open_webui.models.groups import Groups from open_webui.models.tools import Tools from open_webui.models.users import UserModel +from open_webui.utils.chat_id import is_saved_chat_id from open_webui.tools.builtin import ( add_memory, calculate_timestamp, @@ -61,14 +62,17 @@ from open_webui.tools.builtin import ( fetch_url, generate_image, get_current_timestamp, + grep_chat_files, grep_knowledge_files, kb_exec, + list_chat_files, list_automations, list_knowledge, list_knowledge_bases, list_memories, list_memory_paths, notify, + query_chat_files, query_knowledge_bases, query_knowledge_files, read_memory_path, @@ -167,7 +171,7 @@ async def build_tool_server_headers( # Interpolate template vars in custom connection headers connection_headers = connection.get('headers', None) if connection_headers and isinstance(connection_headers, dict): - headers.update(get_custom_headers(connection_headers, user, metadata)) + headers.update(await get_custom_headers(connection_headers, user, metadata)) # Add user info headers if enabled if ENABLE_FORWARD_USER_INFO_HEADERS and user: @@ -183,13 +187,16 @@ async def build_tool_server_headers( # Let no function be called without need, and let what # it yields justify the cost of running it. async def get_async_tool_function_and_apply_extra_params( - function: Callable, extra_params: dict + function: Callable, extra_params: dict, function_introspection=None ) -> Callable[..., Awaitable]: - sig = inspect.signature(function) - try: - type_hints = get_type_hints(function) - except Exception: - type_hints = {} + if function_introspection is None: + sig = inspect.signature(function) + try: + type_hints = get_type_hints(function) + except Exception: + type_hints = {} + else: + sig, type_hints = function_introspection def coerce_kwargs(kwargs): for name, value in kwargs.items(): @@ -471,6 +478,45 @@ async def get_tools(request: Request, tool_ids: list[str], user: UserModel, extr return tools_dict +def get_attached_knowledge(model: dict, metadata: dict) -> list[dict]: + model_meta = model.get('info', {}).get('meta', {}) + knowledge = [] + seen = set() + + for source, items in ( + ('model', model_meta.get('knowledge') or []), + ('folder', metadata.get('folder_knowledge') or []), + ): + for item in items: + if not isinstance(item, dict): + continue + key = (item.get('type'), item.get('id')) + if not all(key) or key in seen: + continue + knowledge.append({**item, 'source': source}) + seen.add(key) + + file_context_enabled = (model_meta.get('capabilities') or {}).get('file_context', True) + if not file_context_enabled: + for item in metadata.get('files') or []: + if not isinstance(item, dict) or item.get('type') not in ('collection', 'note'): + continue + key = (item.get('type'), item.get('id')) + if not all(key) or key in seen: + continue + knowledge.append( + { + 'type': item.get('type'), + 'id': item.get('id'), + 'name': item.get('name'), + 'source': 'chat', + } + ) + seen.add(key) + + return knowledge + + async def get_builtin_tools( request: Request, extra_params: dict, features: dict = None, model: dict = None ) -> dict[str, dict]: @@ -518,18 +564,42 @@ async def get_builtin_tools( await Config.get('user.permissions'), ) + async def has_user_chat_permission(permission_key: str) -> bool: + if user.get('role') == 'admin': + return True + return await has_permission( + user.get('id', ''), + f'chat.{permission_key}', + await Config.get('user.permissions'), + ) + # Time utilities - available for date calculations if is_builtin_tool_enabled('time'): builtin_functions.extend([get_current_timestamp, calculate_timestamp]) + metadata = extra_params.get('__metadata__') or {} + chat_files = metadata.get('files') or extra_params.get('__files__') or [] + has_chat_files = any( + isinstance(item, dict) + and item.get('type', 'file') == 'file' + and (item.get('id') or item.get('url')) + and not str(item.get('id') or item.get('url')).startswith(('http://', 'https://', 'data:')) + for item in chat_files + ) + + if ( + is_builtin_tool_enabled('files') + and get_model_capability('file_upload') + and not get_model_capability('file_context') + and has_chat_files + and await has_user_chat_permission('file_upload') + ): + builtin_functions.extend([list_chat_files, query_chat_files, grep_chat_files, view_file]) + # Knowledge base tools - conditional injection based on model knowledge # If model has attached knowledge (any type), only provide query_knowledge_files # Otherwise, provide all KB browsing tools - model_knowledge = model.get('info', {}).get('meta', {}).get('knowledge', []) - # Merge folder-attached knowledge so builtin tools can search it - folder_knowledge = extra_params.get('__metadata__', {}).get('folder_knowledge') - if folder_knowledge: - model_knowledge = list(model_knowledge or []) + list(folder_knowledge) + model_knowledge = get_attached_knowledge(model, metadata) if is_builtin_tool_enabled('knowledge'): from open_webui.env import ENABLE_KB_EXEC @@ -639,10 +709,9 @@ async def get_builtin_tools( ): builtin_functions.append(execute_code) - metadata = extra_params.get('__metadata__') or {} chat_id = metadata.get('chat_id') or '' chat = None - if chat_id and not chat_id.startswith(('local:', 'channel:')): + if is_saved_chat_id(chat_id): chat = await Chats.get_chat_by_id(chat_id) # Notes tools - search, view, create, and update user's notes @@ -667,7 +736,8 @@ async def get_builtin_tools( builtin_functions.append(view_skill) # Task management - break down complex work into trackable steps - if is_builtin_tool_enabled('tasks'): + # Task state is stored on the chats row; local/channel IDs do not have one. + if is_builtin_tool_enabled('tasks') and is_saved_chat_id(chat_id): builtin_functions.extend([create_tasks, update_task]) # Automation tools - create and manage scheduled automations from chat @@ -707,16 +777,15 @@ async def get_builtin_tools( '__event_emitter__': extra_params.get('__event_emitter__'), '__event_call__': extra_params.get('__event_call__'), '__metadata__': extra_params.get('__metadata__'), + '__files__': chat_files, '__chat_id__': extra_params.get('__chat_id__'), '__message_id__': extra_params.get('__message_id__'), '__model_knowledge__': model_knowledge, }, + get_builtin_function_introspection(func), ) - # Generate spec from function - pydantic_model = convert_function_to_pydantic_model(func) - spec = convert_pydantic_model_to_openai_function_spec(pydantic_model) - spec = clean_openai_tool_schema(spec) + spec = get_builtin_tool_spec(func) if func.__name__ == 'delegate_task' and not config.get('subagents.background_enabled'): parameters = spec.get('parameters', {}) parameters.get('properties', {}).pop('background', None) @@ -788,7 +857,7 @@ def parse_docstring(docstring): return param_descriptions -def convert_function_to_pydantic_model(func: Callable) -> type[BaseModel]: +def convert_function_to_pydantic_model(func: Callable, function_introspection=None) -> type[BaseModel]: """ Converts a Python function's type hints and docstring to a Pydantic model, including support for nested types, default values, and descriptions. @@ -800,8 +869,11 @@ def convert_function_to_pydantic_model(func: Callable) -> type[BaseModel]: Returns: A Pydantic model class. """ - type_hints = get_type_hints(func) - signature = inspect.signature(func) + if function_introspection is None: + type_hints = get_type_hints(func) + signature = inspect.signature(func) + else: + signature, type_hints = function_introspection parameters = signature.parameters docstring = func.__doc__ @@ -867,6 +939,26 @@ def clean_openai_tool_schema(spec: dict) -> dict: return cleaned_spec +@cache +def get_builtin_function_introspection(func: Callable): + try: + type_hints = get_type_hints(func) + except Exception: + type_hints = {} + return inspect.signature(func), type_hints + + +@cache +def build_builtin_tool_spec(func: Callable) -> dict: + pydantic_model = convert_function_to_pydantic_model(func, get_builtin_function_introspection(func)) + spec = convert_pydantic_model_to_openai_function_spec(pydantic_model) + return clean_openai_tool_schema(spec) + + +def get_builtin_tool_spec(func: Callable) -> dict: + return copy.deepcopy(build_builtin_tool_spec(func)) + + def get_functions_from_tool(tool: object) -> list[Callable]: return [ getattr(tool, func) @@ -913,23 +1005,22 @@ def resolve_schema(schema, components, resolved_schemas=None): # Avoid infinite recursion on circular references return {} - resolved_schemas.add(schema_name) - ref_parts = ref_path.strip('#/').split('/') resolved = components for part in ref_parts[1:]: # Skip the initial 'components' resolved = resolved.get(part, {}) - return resolve_schema(resolved, components, resolved_schemas) + # Per-path visited set so sibling refs to the same schema still resolve + return resolve_schema(resolved, components, resolved_schemas | {schema_name}) resolved_schema = copy.deepcopy(schema) # Recursively resolve inner schemas if 'properties' in resolved_schema: for prop, prop_schema in resolved_schema['properties'].items(): - resolved_schema['properties'][prop] = resolve_schema(prop_schema, components) + resolved_schema['properties'][prop] = resolve_schema(prop_schema, components, resolved_schemas) if 'items' in resolved_schema: - resolved_schema['items'] = resolve_schema(resolved_schema['items'], components) + resolved_schema['items'] = resolve_schema(resolved_schema['items'], components, resolved_schemas) # Resolve composition keywords (oneOf, anyOf, allOf) which may contain $ref for keyword in ('oneOf', 'anyOf', 'allOf'): @@ -1234,6 +1325,8 @@ async def get_terminal_tools( connection = next((c for c in connections if c.get('id') == terminal_id), None) if connection is None: raise RuntimeError(f"Terminal server '{terminal_id}' not found") + if not connection.get('enabled', True): + raise RuntimeError(f"Terminal server '{terminal_id}' is disabled") user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id)} if not await has_connection_access(user, connection, user_group_ids): @@ -1266,15 +1359,19 @@ async def get_terminal_tools( headers.update(bearer_auth_header(oauth_token.get('access_token', ''))) # auth_type == "none": no Authorization header - system_prompt = server_data.get('system_prompt') - # Use chat_id as the per-session key for cwd tracking metadata = extra_params.get('__metadata__', {}) session_id = metadata.get('chat_id') if session_id: headers['X-Session-Id'] = session_id - terminal_cwd = await get_terminal_cwd(server_data['url'], headers, cookies) + # Fetch live with the user's credentials so prompt changes apply without a restart + terminal_cwd, system_prompt = await asyncio.gather( + get_terminal_cwd(server_data['url'], headers, cookies), + get_terminal_system_prompt(server_data['url'], headers, cookies), + ) + if not system_prompt: + system_prompt = server_data.get('system_prompt') tools_dict = {} for spec in specs: diff --git a/backend/open_webui/utils/webhook.py b/backend/open_webui/utils/webhook.py index d3026ffac6..9430c6ff67 100644 --- a/backend/open_webui/utils/webhook.py +++ b/backend/open_webui/utils/webhook.py @@ -34,8 +34,12 @@ async def post_webhook(name: str, url: str, message: str, event_data: dict, desc # caller-controlled (user notification settings under # ENABLE_USER_WEBHOOKS, automation notification triggers). await asyncio.to_thread(validate_url, url) - payload = {} + except Exception as e: + log.warning('Webhook skipped, URL invalid or not publicly resolvable: %s', e) + return False + try: + payload = {} # Slack and Google Chat Webhooks if 'https://hooks.slack.com' in url or 'https://chat.googleapis.com' in url: payload['text'] = _event_text(message, description, event_data) diff --git a/backend/requirements-min.txt b/backend/requirements-min.txt index 9d54afe476..a7a19a2257 100644 --- a/backend/requirements-min.txt +++ b/backend/requirements-min.txt @@ -2,13 +2,13 @@ # WIP: use this as a reference to build a minimal docker image fastapi==0.136.3 -uvicorn[standard]==0.41.0 +uvicorn[standard]==0.51.0 pydantic==2.13.4 python-multipart==0.0.32 itsdangerous==2.2.0 python-socketio==5.16.2 -python-jose==3.5.0 +orjson==3.11.9 cryptography bcrypt==5.0.0 argon2-cffi==25.1.0 diff --git a/backend/requirements.txt b/backend/requirements.txt index 3885b6d843..39f666f6d9 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,11 +1,11 @@ fastapi==0.136.3 -uvicorn[standard]==0.41.0 +uvicorn[standard]==0.51.0 pydantic==2.13.4 python-multipart==0.0.32 itsdangerous==2.2.0 python-socketio==5.16.2 -python-jose==3.5.0 +orjson==3.11.9 cryptography==48.0.0 bcrypt==5.0.0 argon2-cffi==25.1.0 @@ -14,7 +14,9 @@ authlib==1.7.2 joserfc==1.7.4 requests==2.34.2 +regex==2026.5.9 # supports a per-search timeout, which `re` does not aiohttp==3.13.5 # do not update to 3.13.3 - broken +aiodns==4.0.4 # makes aiohttp resolve DNS on the event loop instead of the threadpool async-timeout==5.0.1 aiocache==0.12.3 aiofiles==25.1.0 @@ -78,6 +80,7 @@ unstructured==0.22.31 nltk==3.9.4 Markdown==3.10.2 beautifulsoup4==4.14.3 +lxml==6.1.1 pypandoc==1.17 pandas==3.0.3 openpyxl==3.1.5 diff --git a/pyproject.toml b/pyproject.toml index c4790af4dd..a5bf684d0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,13 +7,13 @@ authors = [ license = { file = "LICENSE" } dependencies = [ "fastapi==0.136.3", - "uvicorn[standard]==0.41.0", + "uvicorn[standard]==0.51.0", "pydantic==2.13.4", "python-multipart==0.0.32", "itsdangerous==2.2.0", "python-socketio==5.16.2", - "python-jose==3.5.0", + "orjson==3.11.9", "cryptography==48.0.0", "bcrypt==5.0.0", "argon2-cffi==25.1.0", @@ -23,6 +23,7 @@ dependencies = [ "requests==2.34.2", "aiohttp==3.13.5", # do not update to 3.13.3 - broken + "aiodns==4.0.4", # makes aiohttp resolve DNS on the event loop instead of the threadpool "async-timeout==5.0.1", "aiocache==0.12.3", "aiofiles==25.1.0", @@ -51,6 +52,7 @@ dependencies = [ "asgiref==3.11.1", "tiktoken==0.13.0", + "regex==2026.5.9", "mcp==1.27.2", "openai==2.29.0", @@ -85,6 +87,7 @@ dependencies = [ "nltk==3.9.4", "Markdown==3.10.2", "beautifulsoup4==4.14.3", + "lxml==6.1.1", "pypandoc==1.17", "pandas==3.0.3", "openpyxl==3.1.5", diff --git a/src/app.css b/src/app.css index 04628d7a8e..1d9c74770e 100644 --- a/src/app.css +++ b/src/app.css @@ -410,6 +410,11 @@ input[type='number'] { @apply line-clamp-1 absolute; } +/* #676767 is 3.17:1 on the dark canvas; the light value already passes. */ +html.high-contrast.dark .ProseMirror p.is-editor-empty:first-child::before { + color: var(--color-gray-500); +} + .tiptap ul[data-type='taskList'] { list-style: none; margin-left: 0; @@ -680,7 +685,7 @@ input[type='number'] { } .tiptap tr { - @apply bg-white dark:bg-gray-900 dark:border-gray-850 text-xs; + @apply dark:border-gray-850 text-xs; } .tippy-box[data-theme~='transparent'] { @@ -838,3 +843,78 @@ body { #note-content-container .ProseMirror { padding-bottom: 2rem; /* space for the bottom toolbar */ } + +/* High Contrast Mode: placeholders bottom out at 1.58:1 (WCAG 1.4.3 wants 4.5:1). */ +@layer utilities { + html.high-contrast:not(.dark) :is(input, textarea)::placeholder { + color: var(--color-gray-600); + } + + html.high-contrast.dark :is(input, textarea)::placeholder { + color: var(--color-gray-500); + } +} + +/* High Contrast Mode: muted text fails WCAG 1.4.3 (2.07:1 light, 3.12:1 dark). + :where() keeps these at low specificity so hover variants still win. */ +@layer utilities { + html:where(.high-contrast):not(:where(.dark)) .text-gray-400 { + color: var(--color-gray-600); + } + + html:where(.high-contrast).dark .dark\:text-gray-600 { + color: var(--color-gray-400); + } + + /* Elements that hover to a lighter grey than the new resting colour. */ + html:where(.high-contrast):not(:where(.dark)) .hover\:text-gray-500:hover { + color: var(--color-gray-800); + } +} + +/* High Contrast Mode: gray-500 muted text is 2.77:1 in light (WCAG 1.4.3 wants 4.5:1). + The utility stays in the layer so hover variants still outrank it; the classes below + are unlayered, so their override has to be too. */ +@layer utilities { + html:where(.high-contrast):not(:where(.dark)) .text-gray-500 { + color: var(--color-gray-600); + } +} + +html.high-contrast:not(.dark) :is(.app-muted, .app-icon-muted, .tiptap table) { + color: var(--color-gray-600); +} + +/* High Contrast Mode: the lightest muted pair, 1.58:1 in light and 2.14:1 in dark. + text-gray-400/70 is an icon colour, so 1.4.11 governs it, and 2.07:1 misses that too. */ +@layer utilities { + html:where(.high-contrast):not(:where(.dark)) :is(.text-gray-300, .text-gray-400\/70) { + color: var(--color-gray-600); + } + + html:where(.high-contrast).dark .dark\:text-gray-700 { + color: var(--color-gray-400); + } + + /* Hover states that land lighter than the new resting colour. */ + html:where(.high-contrast):not(:where(.dark)) .hover\:text-gray-500:hover { + color: var(--color-gray-800); + } + + html:where(.high-contrast):not(:where(.dark)) .group:hover .group-hover\:text-gray-500 { + color: var(--color-gray-800); + } +} + +/* Autocompletion ghost text is 2.65:1 in light; the dark canvas already passes. */ +html.high-contrast:not(.dark) .ai-autocompletion::after { + color: var(--color-gray-600); +} + +/* The shimmer gradient is 2.10:1 in light, and clipping it to the text leaves no + solid colour to raise; render it as flat text instead. */ +html.high-contrast:not(.dark) .shimmer { + background: none; + color: var(--color-gray-700); + -webkit-text-fill-color: var(--color-gray-700); +} diff --git a/src/lib/apis/automations/index.ts b/src/lib/apis/automations/index.ts index a79fe1ddc8..593a56cab1 100644 --- a/src/lib/apis/automations/index.ts +++ b/src/lib/apis/automations/index.ts @@ -14,6 +14,7 @@ export type AutomationData = { export type AutomationForm = { name: string; + folder_id?: string | null; data: AutomationData; meta?: { system_prompt?: string; @@ -36,6 +37,7 @@ export type AutomationRunModel = { export type AutomationResponse = { id: string; user_id: string; + folder_id: string | null; name: string; data: AutomationData; meta: Record | null; @@ -53,7 +55,8 @@ export const getAutomationItems = async ( token: string, query: string | null, status: string | null, - page: number + page: number, + folder_id?: string | null ): Promise<{ items: AutomationResponse[]; total: number }> => { let error = null; @@ -67,6 +70,9 @@ export const getAutomationItems = async ( if (page) { searchParams.append('page', page.toString()); } + if (folder_id !== undefined && folder_id !== null) { + searchParams.append('folder_id', folder_id); + } const res = await fetch(`${WEBUI_API_BASE_URL}/automations/list?${searchParams.toString()}`, { method: 'GET', diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts index 0804a0f502..b55df4b72d 100644 --- a/src/lib/apis/chats/index.ts +++ b/src/lib/apis/chats/index.ts @@ -885,6 +885,62 @@ export const toggleChatPinnedStatusById = async (token: string, id: string) => { return res; }; +export const markChatUnreadById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/unread`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = 'detail' in err ? err.detail : err; + console.error(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const markChatsRead = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/read`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = 'detail' in err ? err.detail : err; + console.error(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const cloneChatById = async (token: string, id: string, title?: string) => { let error = null; diff --git a/src/lib/apis/folders/index.ts b/src/lib/apis/folders/index.ts index d82f591289..4e50b6a7f9 100644 --- a/src/lib/apis/folders/index.ts +++ b/src/lib/apis/folders/index.ts @@ -235,6 +235,34 @@ export const deleteFolderById = async (token: string, id: string, deleteContents return res; }; +export const markFolderChatsReadById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/read`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.error(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const updateFolderAccessById = async (token: string, id: string, accessGrants: any[]) => { let error = null; diff --git a/src/lib/apis/knowledge/index.ts b/src/lib/apis/knowledge/index.ts index feb63ccdd8..f0a6e4d140 100644 --- a/src/lib/apis/knowledge/index.ts +++ b/src/lib/apis/knowledge/index.ts @@ -375,7 +375,9 @@ export const searchKnowledgeBases = async ( query: string | null = null, viewOption: string | null = null, page: number | null = null, - source: string | null = null + source: string | null = null, + orderBy: string | null = null, + direction: string | null = null ) => { let error = null; @@ -384,6 +386,8 @@ export const searchKnowledgeBases = async ( if (viewOption) searchParams.append('view_option', viewOption); if (source) searchParams.append('source', source); if (page) searchParams.append('page', page.toString()); + if (orderBy) searchParams.append('order_by', orderBy); + if (direction) searchParams.append('direction', direction); const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/search?${searchParams.toString()}`, { method: 'GET', diff --git a/src/lib/apis/retrieval/index.ts b/src/lib/apis/retrieval/index.ts index dccb5950b3..fc5a7e8274 100644 --- a/src/lib/apis/retrieval/index.ts +++ b/src/lib/apis/retrieval/index.ts @@ -52,6 +52,7 @@ type YoutubeConfigForm = { type RAGConfigForm = { PDF_EXTRACT_IMAGES?: boolean; + CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES?: string[]; ENABLE_GOOGLE_DRIVE_INTEGRATION?: boolean; ENABLE_ONEDRIVE_INTEGRATION?: boolean; EXTERNAL_DOCUMENT_LOADER_HEADERS?: Record; diff --git a/src/lib/apis/terminal/index.ts b/src/lib/apis/terminal/index.ts index ee38a9a8fa..eedbcc3eed 100644 --- a/src/lib/apis/terminal/index.ts +++ b/src/lib/apis/terminal/index.ts @@ -143,7 +143,8 @@ export const downloadFileBlob = async ( if (!res || !res.ok) return null; const filename = path.split('/').pop() ?? 'file'; - const blob = await res.blob(); + const blob = await res.blob().catch(() => null); + if (!blob) return null; return { blob, filename }; }; @@ -170,7 +171,8 @@ export const archiveFromTerminal = async ( const disposition = res.headers.get('content-disposition') ?? ''; const match = disposition.match(/filename="?([^"]+)"?/); const filename = match?.[1] ?? 'download.zip'; - const blob = await res.blob(); + const blob = await res.blob().catch(() => null); + if (!blob) return null; return { blob, filename }; }; diff --git a/src/lib/components/AddConnectionModal.svelte b/src/lib/components/AddConnectionModal.svelte index 6715c80b1a..16616fc247 100644 --- a/src/lib/components/AddConnectionModal.svelte +++ b/src/lib/components/AddConnectionModal.svelte @@ -63,7 +63,7 @@ const inputClass = 'bg-transparent outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; const selectClass = - 'dark:bg-gray-900 bg-transparent pr-5 outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; + 'bg-transparent pr-5 outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; const parsePassthroughParams = (value: string) => value @@ -597,6 +597,7 @@ + diff --git a/src/lib/components/AddTerminalServerModal.svelte b/src/lib/components/AddTerminalServerModal.svelte index 9e8a003a8e..0cf622b86f 100644 --- a/src/lib/components/AddTerminalServerModal.svelte +++ b/src/lib/components/AddTerminalServerModal.svelte @@ -62,7 +62,7 @@ const inputClass = 'bg-transparent outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; const selectClass = - 'dark:bg-gray-900 bg-transparent pr-5 outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; + 'bg-transparent pr-5 outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; const stringifyJson = (value: object | null | undefined) => { return JSON.stringify(value && Object.keys(value).length ? value : {}, null, 2); diff --git a/src/lib/components/AddToolServerModal.svelte b/src/lib/components/AddToolServerModal.svelte index 27efb8bcec..4bb310140e 100644 --- a/src/lib/components/AddToolServerModal.svelte +++ b/src/lib/components/AddToolServerModal.svelte @@ -72,7 +72,7 @@ const inputClass = 'bg-transparent outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; const selectClass = - 'dark:bg-gray-900 bg-transparent pr-5 outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; + 'bg-transparent pr-5 outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'; const registerOAuthClientHandler = async () => { if (url === '') { diff --git a/src/lib/components/AutomationModal.svelte b/src/lib/components/AutomationModal.svelte index d6dd0ab176..23028b3bc8 100644 --- a/src/lib/components/AutomationModal.svelte +++ b/src/lib/components/AutomationModal.svelte @@ -8,6 +8,9 @@ import ScheduleDropdown from '$lib/components/automations/ScheduleDropdown.svelte'; import ModelDropdown from '$lib/components/automations/ModelDropdown.svelte'; + import FolderDropdown from '$lib/components/automations/FolderDropdown.svelte'; + import { getFolders } from '$lib/apis/folders'; + import { folders } from '$lib/stores'; import { createAutomation, @@ -26,9 +29,11 @@ let name = ''; let prompt = ''; let model_id = ''; + let folder_id = ''; let is_active = true; let loading = false; + let foldersLoaded = false; // Schedule dropdown ref let scheduleDropdown: ScheduleDropdown; @@ -49,6 +54,7 @@ try { const form: AutomationForm = { name: name.trim(), + folder_id: folder_id || null, data: { prompt: prompt.trim(), model_id: model_id.trim(), @@ -77,11 +83,17 @@ const init = async () => { await tick(); + if (!foldersLoaded && ($folders ?? []).length === 0) { + const res = await getFolders(localStorage.token).catch(() => null); + if (res) folders.set(res); + foldersLoaded = true; + } if (automation) { name = automation.name; prompt = automation.data.prompt; model_id = automation.data.model_id; + folder_id = automation.folder_id ?? ''; is_active = automation.is_active; if (scheduleDropdown) { scheduleDropdown.parseRrule(automation.data.rrule); @@ -90,6 +102,9 @@ name = cloneFrom.name; prompt = cloneFrom.data.prompt; model_id = cloneFrom.data.model_id; + folder_id = ($folders ?? []).some((folder) => folder.id === cloneFrom.folder_id) + ? (cloneFrom.folder_id ?? '') + : ''; is_active = true; if (scheduleDropdown) { scheduleDropdown.parseRrule(cloneFrom.data.rrule); @@ -98,6 +113,7 @@ name = ''; prompt = ''; model_id = ''; + folder_id = ''; is_active = true; } }; @@ -138,14 +154,18 @@ -
-
+
+
+ +
-
+
{:else if selected !== null}
-
- - - -
-
{#if selected === 'ollama'} diff --git a/src/lib/components/admin/Settings/Pipelines.svelte b/src/lib/components/admin/Settings/Pipelines.svelte index 0c62f30523..025ab35671 100644 --- a/src/lib/components/admin/Settings/Pipelines.svelte +++ b/src/lib/components/admin/Settings/Pipelines.svelte @@ -422,8 +422,9 @@ - + {:else} - + - + {#if webConfig.ENABLE_WEB_SEARCH_CONFIRMATION} @@ -1111,15 +1116,20 @@ description={webConfig.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL ? $i18n.t('Inject the entire content as context for comprehensive processing.') : $i18n.t('Use segmented retrieval for focused and relevant content extraction.')} + let:labelId > - + - + - + @@ -1163,8 +1174,12 @@ - + {:else if webConfig.WEB_LOADER_ENGINE === 'playwright'}
diff --git a/src/lib/components/admin/Users/Groups/Permissions.svelte b/src/lib/components/admin/Users/Groups/Permissions.svelte index 802f11662d..2f276ab364 100644 --- a/src/lib/components/admin/Users/Groups/Permissions.svelte +++ b/src/lib/components/admin/Users/Groups/Permissions.svelte @@ -48,7 +48,7 @@
{$i18n.t('Models Access')}
- +
{#if permissions.workspace.models} @@ -57,13 +57,19 @@
{$i18n.t('Import Models')}
- +
{$i18n.t('Export Models')}
- +
{:else if defaultPermissions?.workspace?.models} @@ -80,7 +86,10 @@
{$i18n.t('Knowledge Access')}
- +
{#if defaultPermissions?.workspace?.knowledge && !permissions.workspace.knowledge}
@@ -96,7 +105,7 @@
{$i18n.t('Prompts Access')}
- +
{#if permissions.workspace.prompts} @@ -105,13 +114,19 @@
{$i18n.t('Import Prompts')}
- +
{$i18n.t('Export Prompts')}
- +
{:else if defaultPermissions?.workspace?.prompts} @@ -135,7 +150,7 @@
{$i18n.t('Tools Access')}
- + {#if permissions.workspace.tools} @@ -144,13 +159,19 @@
{$i18n.t('Import Tools')}
- +
{$i18n.t('Export Tools')}
- +
{:else if defaultPermissions?.workspace?.tools} @@ -174,7 +195,7 @@
{$i18n.t('Skills Access')}
- + {#if permissions.workspace.skills} @@ -183,13 +204,19 @@
{$i18n.t('Import Skills')}
- +
{$i18n.t('Export Skills')}
- +
{:else if defaultPermissions?.workspace?.skills} @@ -212,7 +239,7 @@
{$i18n.t('Models Sharing')}
- + {#if defaultPermissions?.sharing?.models && !permissions.sharing.models}
@@ -229,7 +256,10 @@
{$i18n.t('Models Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_models && !permissions.sharing.public_models}
@@ -246,7 +276,10 @@
{$i18n.t('Knowledge Sharing')}
- +
{#if defaultPermissions?.sharing?.knowledge && !permissions.sharing.knowledge}
@@ -263,7 +296,10 @@
{$i18n.t('Knowledge Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_knowledge && !permissions.sharing.public_knowledge}
@@ -280,7 +316,7 @@
{$i18n.t('Prompts Sharing')}
- +
{#if defaultPermissions?.sharing?.prompts && !permissions.sharing.prompts}
@@ -297,7 +333,10 @@
{$i18n.t('Prompts Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_prompts && !permissions.sharing.public_prompts}
@@ -314,7 +353,7 @@
{$i18n.t('Tools Sharing')}
- +
{#if defaultPermissions?.sharing?.tools && !permissions.sharing.tools}
@@ -331,7 +370,10 @@
{$i18n.t('Tools Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_tools && !permissions.sharing.public_tools}
@@ -348,7 +390,7 @@
{$i18n.t('Skills Sharing')}
- +
{#if defaultPermissions?.sharing?.skills && !permissions.sharing.skills}
@@ -365,7 +407,10 @@
{$i18n.t('Skills Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_skills && !permissions.sharing.public_skills}
@@ -382,7 +427,7 @@
{$i18n.t('Notes Sharing')}
- +
{#if defaultPermissions?.sharing?.notes && !permissions.sharing.notes}
@@ -399,7 +444,10 @@
{$i18n.t('Notes Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_notes && !permissions.sharing.public_notes}
@@ -416,7 +464,7 @@
{$i18n.t('Folders Sharing')}
- +
{#if defaultPermissions?.sharing?.folders && !permissions.sharing.folders}
@@ -433,7 +481,10 @@
{$i18n.t('Chats Public Sharing')}
- +
{#if defaultPermissions?.sharing?.public_chats && !permissions.sharing.public_chats}
@@ -443,6 +494,25 @@
{/if} + +
+
+
+ {$i18n.t('Chats Open Sharing')} +
+ +
+ {#if defaultPermissions?.sharing?.open_chats && !permissions.sharing.open_chats} +
+
+ {$i18n.t('This is a default user permission and will remain enabled.')} +
+
+ {/if} +
{/if} {#if permissions.features.calendar} @@ -451,7 +521,10 @@
{$i18n.t('Calendars Public Sharing')}
- + {#if defaultPermissions?.sharing?.public_calendars && !permissions.sharing.public_calendars}
@@ -474,7 +547,10 @@
{$i18n.t('Allow Sharing With Users')}
- +
{#if defaultPermissions?.access_grants?.allow_users && !permissions.access_grants.allow_users}
@@ -490,7 +566,10 @@
{$i18n.t('Allow Sharing With Groups')}
- +
{#if defaultPermissions?.access_grants?.allow_groups && !permissions.access_grants.allow_groups}
@@ -512,7 +591,10 @@
{$i18n.t('Allow File Upload')}
- +
{#if defaultPermissions?.chat?.file_upload && !permissions.chat.file_upload}
@@ -528,7 +610,7 @@
{$i18n.t('Allow Web Upload')}
- +
{#if defaultPermissions?.chat?.web_upload && !permissions.chat.web_upload}
@@ -544,7 +626,7 @@
{$i18n.t('Allow Chat Controls')}
- +
{#if defaultPermissions?.chat?.controls && !permissions.chat.controls}
@@ -561,7 +643,7 @@
{$i18n.t('Allow Chat Valves')}
- +
{#if defaultPermissions?.chat?.valves && !permissions.chat.valves}
@@ -577,7 +659,10 @@
{$i18n.t('Allow Chat System Prompt')}
- +
{#if defaultPermissions?.chat?.system_prompt && !permissions.chat.system_prompt}
@@ -593,7 +678,7 @@
{$i18n.t('Allow Chat Params')}
- +
{#if defaultPermissions?.chat?.params && !permissions.chat.params}
@@ -610,7 +695,7 @@
{$i18n.t('Allow Chat Edit')}
- +
{#if defaultPermissions?.chat?.edit && !permissions.chat.edit}
@@ -626,7 +711,7 @@
{$i18n.t('Allow Chat Delete')}
- +
{#if defaultPermissions?.chat?.delete && !permissions.chat.delete}
@@ -642,7 +727,10 @@
{$i18n.t('Allow Delete Messages')}
- +
{#if defaultPermissions?.chat?.delete_message && !permissions.chat.delete_message}
@@ -658,7 +746,10 @@
{$i18n.t('Allow Continue Response')}
- +
{#if defaultPermissions?.chat?.continue_response && !permissions.chat.continue_response}
@@ -674,7 +765,10 @@
{$i18n.t('Allow Regenerate Response')}
- +
{#if defaultPermissions?.chat?.regenerate_response && !permissions.chat.regenerate_response}
@@ -690,7 +784,10 @@
{$i18n.t('Allow Rate Response')}
- +
{#if defaultPermissions?.chat?.rate_response && !permissions.chat.rate_response}
@@ -706,7 +803,7 @@
{$i18n.t('Allow Chat Share')}
- +
{#if defaultPermissions?.chat?.share && !permissions.chat.share}
@@ -722,7 +819,7 @@
{$i18n.t('Allow Chat Export')}
- +
{#if defaultPermissions?.chat?.export && !permissions.chat.export}
@@ -738,7 +835,7 @@
{$i18n.t('Allow Chat Import')}
- +
{#if defaultPermissions?.chat?.import && !permissions.chat['import']}
@@ -754,7 +851,7 @@
{$i18n.t('Allow Speech to Text')}
- +
{#if defaultPermissions?.chat?.stt && !permissions.chat.stt}
@@ -770,7 +867,7 @@
{$i18n.t('Allow Text to Speech')}
- +
{#if defaultPermissions?.chat?.tts && !permissions.chat.tts}
@@ -786,7 +883,7 @@
{$i18n.t('Allow Call')}
- +
{#if defaultPermissions?.chat?.call && !permissions.chat.call}
@@ -802,7 +899,10 @@
{$i18n.t('Allow Multiple Models in Chat')}
- +
{#if defaultPermissions?.chat?.multiple_models && !permissions.chat.multiple_models}
@@ -818,7 +918,10 @@
{$i18n.t('Allow Temporary Chat')}
- +
{#if defaultPermissions?.chat?.temporary && !permissions.chat.temporary}
@@ -835,7 +938,10 @@
{$i18n.t('Enforce Temporary Chat')}
- +
{#if defaultPermissions?.chat?.temporary_enforced && !permissions.chat.temporary_enforced}
@@ -858,7 +964,7 @@
{$i18n.t('API Keys')}
- +
{#if defaultPermissions?.features?.api_keys && !permissions.features.api_keys}
@@ -874,7 +980,7 @@
{$i18n.t('Notes')}
- +
{#if defaultPermissions?.features?.notes && !permissions.features.notes}
@@ -890,7 +996,7 @@
{$i18n.t('Channels')}
- +
{#if defaultPermissions?.features?.channels && !permissions.features.channels}
@@ -906,7 +1012,7 @@
{$i18n.t('Folders')}
- +
{#if defaultPermissions?.features?.folders && !permissions.features.folders}
@@ -922,7 +1028,10 @@
{$i18n.t('Direct Tool Servers')}
- +
{#if defaultPermissions?.features?.direct_tool_servers && !permissions.features.direct_tool_servers}
@@ -938,7 +1047,7 @@
{$i18n.t('Web Search')}
- +
{#if defaultPermissions?.features?.web_search && !permissions.features.web_search}
@@ -954,7 +1063,10 @@
{$i18n.t('Image Generation')}
- +
{#if defaultPermissions?.features?.image_generation && !permissions.features.image_generation}
@@ -970,7 +1082,10 @@
{$i18n.t('Code Interpreter')}
- +
{#if defaultPermissions?.features?.code_interpreter && !permissions.features.code_interpreter}
@@ -986,7 +1101,7 @@
{$i18n.t('Memories')}
- +
{#if defaultPermissions?.features?.memories && !permissions.features.memories}
@@ -1008,7 +1123,7 @@
{$i18n.t('Automations')}
- + {#if defaultPermissions?.features?.automations && !permissions.features.automations}
@@ -1024,7 +1139,7 @@
{$i18n.t('Calendar')}
- +
{#if defaultPermissions?.features?.calendar && !permissions.features.calendar}
@@ -1040,7 +1155,7 @@
{$i18n.t('User Webhooks')}
- +
{#if defaultPermissions?.features?.webhooks && !permissions.features.webhooks}
@@ -1062,7 +1177,10 @@
{$i18n.t('Interface Settings Access')}
- +
{#if defaultPermissions?.settings?.interface && !permissions.settings.interface}
diff --git a/src/lib/components/admin/Users/Groups/Users.svelte b/src/lib/components/admin/Users/Groups/Users.svelte index 6ee7f427a4..2c2aeab667 100644 --- a/src/lib/components/admin/Users/Groups/Users.svelte +++ b/src/lib/components/admin/Users/Groups/Users.svelte @@ -234,10 +234,11 @@ {#each users as user, userIdx (user?.id ?? userIdx)} - +
{ toggleMember(user.id, e.detail); diff --git a/src/lib/components/admin/Users/UserList.svelte b/src/lib/components/admin/Users/UserList.svelte index 1bd59edbbb..da5b236952 100644 --- a/src/lib/components/admin/Users/UserList.svelte +++ b/src/lib/components/admin/Users/UserList.svelte @@ -72,6 +72,9 @@ } }; + const sortState = (key) => + orderBy === key ? (direction === 'asc' ? 'ascending' : 'descending') : 'none'; + const setSortKey = (key) => { if (orderBy === key) { direction = direction === 'asc' ? 'desc' : 'asc'; @@ -221,12 +224,12 @@ - - - - - @@ -343,7 +346,7 @@ {#each users as user (user.id)} - +
setSortKey('name')} - > -
+
+ setSortKey('role')} - > -
+
+ setSortKey('email')} - > -
+
+ setSortKey('last_active_at')} - > -
+
+ setSortKey('created_at')} - > -
+
+
diff --git a/src/lib/components/automations/AutomationEditor.svelte b/src/lib/components/automations/AutomationEditor.svelte index 32d3a81d9f..4d00c04585 100644 --- a/src/lib/components/automations/AutomationEditor.svelte +++ b/src/lib/components/automations/AutomationEditor.svelte @@ -7,7 +7,8 @@ import localizedFormat from 'dayjs/plugin/localizedFormat'; import type i18nType from '$lib/i18n'; - import { WEBUI_NAME } from '$lib/stores'; + import { WEBUI_NAME, folders } from '$lib/stores'; + import { getFolders } from '$lib/apis/folders'; import { getAutomationById, @@ -42,6 +43,19 @@ let runsLoading = false; let hasMoreRuns = true; let runsPage = 0; + let foldersLoaded = false; + + const ensureFolders = async () => { + if (foldersLoaded || ($folders ?? []).length > 0) return; + const res = await getFolders(localStorage.token).catch(() => null); + if (res) folders.set(res); + foldersLoaded = true; + }; + + const getFolderName = (folderId: string | null): string => + folderId + ? (($folders ?? []).find((folder) => folder.id === folderId)?.name ?? $i18n.t('None')) + : $i18n.t('None'); const formatTime = (ts: number | null): string => { if (!ts) return '-'; @@ -201,6 +215,7 @@ onMount(async () => { is_active = automation.is_active; + await ensureFolders(); await loadRuns(); }); @@ -263,6 +278,15 @@
+
+ + {$i18n.t('Folder')} + + + {getFolderName(automation.folder_id)} + +
+
{$i18n.t('Model')} diff --git a/src/lib/components/automations/FolderDropdown.svelte b/src/lib/components/automations/FolderDropdown.svelte new file mode 100644 index 0000000000..0ab80797d7 --- /dev/null +++ b/src/lib/components/automations/FolderDropdown.svelte @@ -0,0 +1,148 @@ + + + +
+ + {#if folderOptions.length > 0} +
+
+ {$i18n.t('Folders')} +
+ {/if} + + {#each filteredFolderOptions as folder (folder.id)} + {@const path = folderPath(folder)} + + {:else} +
+ {folderOptions.length > 0 ? $i18n.t('No results found') : $i18n.t('No folders')} +
+ {/each} + + diff --git a/src/lib/components/calendar/CalendarEventModal.svelte b/src/lib/components/calendar/CalendarEventModal.svelte index 50d96cdccd..e95c30d6e6 100644 --- a/src/lib/components/calendar/CalendarEventModal.svelte +++ b/src/lib/components/calendar/CalendarEventModal.svelte @@ -214,11 +214,23 @@
{$i18n.t('When')}
- + {#if !allDay} - + – - + {/if}
- {:else if loading} + {:else if loading || ($selectedTerminalId && $terminalServers === null)}
{:else if error}
{error}
@@ -1377,7 +1400,7 @@
{/if} - {#if !loading && !error && !uploading} + {#if !loading && !error && !uploading && !($selectedTerminalId && $terminalServers === null)} {#if creatingFolder}
diff --git a/src/lib/components/chat/FileNav/FilePreview.svelte b/src/lib/components/chat/FileNav/FilePreview.svelte index aa9253f1c0..520c6473a8 100644 --- a/src/lib/components/chat/FileNav/FilePreview.svelte +++ b/src/lib/components/chat/FileNav/FilePreview.svelte @@ -348,6 +348,7 @@ class="flex items-center justify-center gap-3 py-2 px-3 border-t border-gray-100 dark:border-gray-800 text-xs text-gray-500" > {currentSlide + 1} / {fileOfficeSlides.length} {page + 1} / {totalPages} ({totalRows.toLocaleString()} rows)
- {#if $temporaryChatEnabled && ($chatId ?? '').startsWith('local:')} + {#if $temporaryChatEnabled && isTemporaryChatId($chatId)}
{$i18n.t('Temporary Chat')}
diff --git a/src/lib/components/chat/Overview.svelte b/src/lib/components/chat/Overview.svelte index 3708fa9061..94cddcbec2 100644 --- a/src/lib/components/chat/Overview.svelte +++ b/src/lib/components/chat/Overview.svelte @@ -1,17 +1,12 @@ - + diff --git a/src/lib/components/chat/Overview/Flow.svelte b/src/lib/components/chat/Overview/Flow.svelte index d3963e22ae..626398cf30 100644 --- a/src/lib/components/chat/Overview/Flow.svelte +++ b/src/lib/components/chat/Overview/Flow.svelte @@ -1,7 +1,9 @@ + (pinned = !pinned)} + title={pinned ? $i18n.t('Viewport Pinned') : $i18n.t('Viewport Unpinned')} + > + {#if pinned} + + {:else} + + {/if} + setLayoutDirection('vertical')} title="Vertical Layout"> diff --git a/src/lib/components/chat/Overview/Node.svelte b/src/lib/components/chat/Overview/Node.svelte index b4376194cb..09f40b2b99 100644 --- a/src/lib/components/chat/Overview/Node.svelte +++ b/src/lib/components/chat/Overview/Node.svelte @@ -33,7 +33,7 @@ src={`${WEBUI_API_BASE_URL}/users/${data.user.id}/profile/image`} className={'size-5 -translate-y-[1px] flex-shrink-0'} /> -
+
{data?.user?.name ?? 'User'} @@ -54,7 +54,7 @@ className={'size-5 -translate-y-[1px] flex-shrink-0'} /> -
+
{data?.model?.name ?? data?.message?.model ?? 'Assistant'} diff --git a/src/lib/components/chat/Overview/View.svelte b/src/lib/components/chat/Overview/View.svelte index d757c69dd2..35e463d691 100644 --- a/src/lib/components/chat/Overview/View.svelte +++ b/src/lib/components/chat/Overview/View.svelte @@ -1,37 +1,43 @@ @@ -178,10 +176,14 @@ {nodeTypes} {edges} {setLayoutDirection} + bind:pinned on:nodeclick={(e) => { onNodeClick(e.detail); - selectedMessageId = e.detail.node.data.message.id; - fitView({ nodes: [{ id: selectedMessageId }] }); + const clickedMessageId = e.detail.node.data.message.id as string; + selectedMessageId = clickedMessageId; + if (!pinned) { + fitView({ nodes: [{ id: clickedMessageId }] }); + } }} /> {/if} diff --git a/src/lib/components/chat/Placeholder/ChatList.svelte b/src/lib/components/chat/Placeholder/ChatList.svelte index 77bd5ae4ab..aaecdbb73f 100644 --- a/src/lib/components/chat/Placeholder/ChatList.svelte +++ b/src/lib/components/chat/Placeholder/ChatList.svelte @@ -2,7 +2,11 @@ import { getContext } from 'svelte'; import type { Writable } from 'svelte/store'; - const i18n: Writable = getContext('i18n'); + type ChatListI18n = { + t: (key: string, options?: Record) => string; + }; + + const i18n: Writable = getContext('i18n'); import dayjs from 'dayjs'; import localizedFormat from 'dayjs/plugin/localizedFormat'; @@ -12,10 +16,25 @@ import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte'; import ChevronRight from '$lib/components/icons/ChevronRight.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte'; + import Spinner from '$lib/components/common/Spinner.svelte'; + import { chatId, socket } from '$lib/stores'; dayjs.extend(localizedFormat); - export let chats: any[] = []; + type ChatListItem = { + id: string; + title?: string; + updated_at?: number | null; + created_at?: number | null; + last_read_at?: number | null; + active?: boolean; + time_range?: string; + user_id?: string; + owner_name?: string; + [key: string]: unknown; + }; + + export let chats: ChatListItem[] = []; export let chatListLoading = false; export let showOwnerInfo = false; @@ -24,10 +43,10 @@ export let perPage = 10; export let orderBy: 'title' | 'updated_at' = 'updated_at'; export let direction: 'asc' | 'desc' = 'desc'; - export let onPageChange: Function = () => {}; - export let onSort: Function = () => {}; + export let onPageChange: (page: number) => void | Promise = () => {}; + export let onSort: (key: 'title' | 'updated_at') => void | Promise = () => {}; - let chatList: any[] | null = null; + let chatList: ChatListItem[] | null = null; let totalPages = 1; let pages: (number | 'ellipsis')[] = []; @@ -46,6 +65,22 @@ onSort(key); }; + const markChatRead = (chat: ChatListItem, unread: boolean) => { + if (!unread) { + return; + } + + const lastReadAt = Date.now() / 1000; + chatList = (chatList ?? []).map((item) => + item.id === chat.id ? { ...item, last_read_at: lastReadAt } : item + ); + + $socket?.emit('events:chat', { + chat_id: chat.id, + data: { type: 'last_read_at' } + }); + }; + const buildPages = (currentPage: number, pageCount: number): (number | 'ellipsis')[] => { if (pageCount <= 7) { return Array.from({ length: pageCount }, (_, i) => i + 1); @@ -138,6 +173,11 @@ {/if} {#each chatList as chat, idx (chat.id)} + {@const unread = + chat.id !== $chatId && + !chat.active && + (chat.last_read_at == null || + (chat.updated_at != null && chat.updated_at > chat.last_read_at))} {#if (idx === 0 || (idx > 0 && chat.time_range !== chatList[idx - 1].time_range)) && chat?.time_range}
markChatRead(chat, unread)} > -
- {chat?.title} +
+ {#if chat.active} +
+ +
+ {:else if unread} +
+
+
+ {/if} + +
+ {chat?.title} +
@@ -479,6 +500,7 @@ {#if (params?.max_tokens ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('max_tokens', 'max_tokens', -2, 131072, 1, 1, undefined)} {/if}
@@ -620,23 +622,26 @@
@@ -673,29 +678,7 @@ {#if (params?.top_p ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('top_p', 'top_p', 0, 1, 0.05)} {/if}
@@ -728,29 +711,7 @@ {#if (params?.min_p ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('min_p', 'min_p', 0, 1, 0.05)} {/if}
@@ -784,29 +745,7 @@ {#if (params?.frequency_penalty ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('frequency_penalty', 'frequency_penalty', -2, 2, 0.05)} {/if}
@@ -840,29 +779,7 @@ {#if (params?.presence_penalty ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('presence_penalty', 'presence_penalty', -2, 2, 0.05)} {/if}
@@ -893,29 +810,7 @@ {#if (params?.mirostat ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('mirostat', 'mirostat', 0, 2, 1, 1)} {/if}
@@ -948,29 +843,7 @@ {#if (params?.mirostat_eta ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('mirostat_eta', 'mirostat_eta', 0, 1, 0.05)} {/if}
@@ -1004,29 +877,7 @@ {#if (params?.mirostat_tau ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('mirostat_tau', 'mirostat_tau', 0, 10, 0.5)} {/if}
@@ -1058,29 +909,7 @@ {#if (params?.repeat_last_n ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('repeat_last_n', 'repeat_last_n', -1, 128, 1, 1)} {/if}
@@ -1114,29 +943,7 @@ {#if (params?.tfs_z ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('tfs_z', 'tfs_z', 0, 2, 0.05)} {/if}
@@ -1170,29 +977,7 @@ {#if (params?.repeat_penalty ?? null) !== null} -
-
- -
-
- -
-
+ {@render rangeParam('repeat_penalty', 'repeat_penalty', -2, 2, 0.05)} {/if} @@ -1231,7 +1016,7 @@ {params.use_mmap ? $i18n.t('Enabled') : $i18n.t('Disabled')}
- +
{/if} @@ -1273,7 +1058,7 @@
- +
{/if} @@ -1326,6 +1111,7 @@ diff --git a/src/lib/components/common/Valves.svelte b/src/lib/components/common/Valves.svelte index e174a4ef32..8cca8fd583 100644 --- a/src/lib/components/common/Valves.svelte +++ b/src/lib/components/common/Valves.svelte @@ -9,6 +9,7 @@ import Switch from './Switch.svelte'; import SensitiveInput from './SensitiveInput.svelte'; import NativeSelect from './NativeSelect.svelte'; + import MultiSelect from './MultiSelect.svelte'; import MapSelector from './Valves/MapSelector.svelte'; export let valvesSpec = null; @@ -37,7 +38,11 @@ // Initialize to custom value if ((propertySpec?.type ?? null) === 'array') { const defaultArray = propertySpec?.default ?? []; - valves[property] = Array.isArray(defaultArray) ? defaultArray.join(', ') : ''; + if (propertySpec?.input?.type === 'multiselect') { + valves[property] = Array.isArray(defaultArray) ? [...defaultArray] : []; + } else { + valves[property] = Array.isArray(defaultArray) ? defaultArray.join(', ') : ''; + } } else { valves[property] = propertySpec?.default ?? ''; } @@ -95,6 +100,16 @@ /> + {:else if valvesSpec.properties[property]?.input?.type === 'multiselect' && valvesSpec.properties[property]?.input?.options} + { + dispatch('change'); + }} + /> {:else if (valvesSpec.properties[property]?.type ?? null) !== 'string'} + + +
+ + + +
+ + + {#if $pinnedChats.length > 0}
@@ -1422,6 +1570,7 @@ on:change={async () => { initChatList(); }} + onReadStateChange={applyChatReadState} on:tag={(e) => { const { type, name } = e.detail; tagEventHandler(type, name, chat.id); @@ -1486,6 +1635,7 @@ on:change={async () => { initChatList(); }} + onReadStateChange={applyChatReadState} on:tag={(e) => { const { type, name } = e.detail; tagEventHandler(type, name, chat.id); diff --git a/src/lib/components/layout/Sidebar/ChatItem.svelte b/src/lib/components/layout/Sidebar/ChatItem.svelte index 65569af1c6..3e9602ba7b 100644 --- a/src/lib/components/layout/Sidebar/ChatItem.svelte +++ b/src/lib/components/layout/Sidebar/ChatItem.svelte @@ -3,6 +3,15 @@ const invisibleDragImage = new Image(); invisibleDragImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; + + /** + * At most one chat hover preview may be open across all ChatItem instances. + * bits-ui's safe-polygon close only re-evaluates on pointermove, so a + * preview can be left open when the pointer stops on a neighboring row + * while still inside the previous row's grace area; opening a preview + * therefore force-closes whichever one is still up. + */ + let closeActiveHoverPreview: (() => void) | null = null; {#each ownedList as folderId (folderId)} @@ -63,6 +53,7 @@ {shiftKey} {onDelete} {onItemMove} + {onFolderUnreadCounts} on:import={(e) => { dispatch('import', e.detail); }} @@ -88,6 +79,7 @@ {shiftKey} {onDelete} {onItemMove} + {onFolderUnreadCounts} on:import={(e) => { dispatch('import', e.detail); }} diff --git a/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte b/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte index a22efec82f..341b267dac 100644 --- a/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte +++ b/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte @@ -12,6 +12,7 @@ import TrashIcon from '../icons/Trash.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte'; import Download from '../icons/Download.svelte'; + import CheckIcon from '$lib/components/icons/Check.svelte'; export let align: 'start' | 'end' = 'start'; export let onEdit = () => {}; @@ -19,6 +20,7 @@ export let onShare = () => {}; export let onDelete = () => {}; export let onCreateSubFolder = () => {}; + export let onMarkAllRead = () => {}; let show = false; @@ -57,6 +59,19 @@
+ + +
+ -
+
{#if edit} {:else} - {folders[folderId].name} +
+ {folders[folderId].name} +
+ + {#if !folders[folderId]?.shared && (folders[folderId]?.unread_count ?? 0) > 0} +
+ {formatUnreadCount(folders[folderId].unread_count)} +
+ {/if} {/if}
@@ -686,6 +874,7 @@ createSubFolderParentId = folderId; showCreateSubFolderModal = true; }} + onMarkAllRead={markAllReadHandler} >
{ dispatch('import', e.detail); }} @@ -747,6 +937,7 @@ ownerUserId={folders[folderId]?.shared && chat.owner_name ? chat.user_id : null} readonly={chat.user_id !== $user?.id} {shiftKey} + onReadStateChange={applyReadState} on:change={(e) => { dispatch('change', e.detail); }} diff --git a/src/lib/components/layout/Sidebar/Section.svelte b/src/lib/components/layout/Sidebar/Section.svelte index b603b4b5eb..cf55bd8ceb 100644 --- a/src/lib/components/layout/Sidebar/Section.svelte +++ b/src/lib/components/layout/Sidebar/Section.svelte @@ -24,6 +24,12 @@ let loaded = false; let draggedOver = false; + const setOpen = (state: boolean) => { + open = state; + dispatch('change', state); + localStorage.setItem(`${id}-folder-state`, `${state}`); + }; + const onDragOver = (e: DragEvent) => { e.preventDefault(); e.stopPropagation(); @@ -118,21 +124,15 @@ {/if} {#if collapsible} - { - dispatch('change', state); - localStorage.setItem(`${id}-folder-state`, `${state}`); - }} - > +
+ + {#if onAdd}
+ {#if sortKey === 'name'} + {#if sortDirection === 'asc'} + + {:else} + + {/if} + {/if} + -
+
+ {#if sortKey === 'updated_at'} + {#if sortDirection === 'asc'} + + {:else} + + {/if} + {/if} +
diff --git a/src/lib/components/workspace/Knowledge/KnowledgeBase/AddContentMenu.svelte b/src/lib/components/workspace/Knowledge/KnowledgeBase/AddContentMenu.svelte index 25f81f5369..af5e56c5ed 100644 --- a/src/lib/components/workspace/Knowledge/KnowledgeBase/AddContentMenu.svelte +++ b/src/lib/components/workspace/Knowledge/KnowledgeBase/AddContentMenu.svelte @@ -37,6 +37,7 @@
{ if (e.detail === 'checked') { diff --git a/src/lib/components/workspace/Models/DefaultFiltersSelector.svelte b/src/lib/components/workspace/Models/DefaultFiltersSelector.svelte index 9742b16727..80fd6ee862 100644 --- a/src/lib/components/workspace/Models/DefaultFiltersSelector.svelte +++ b/src/lib/components/workspace/Models/DefaultFiltersSelector.svelte @@ -62,6 +62,7 @@
{ if (e.detail === 'checked') { diff --git a/src/lib/components/workspace/Models/FiltersSelector.svelte b/src/lib/components/workspace/Models/FiltersSelector.svelte index 56ff12e5f8..ac2da17042 100644 --- a/src/lib/components/workspace/Models/FiltersSelector.svelte +++ b/src/lib/components/workspace/Models/FiltersSelector.svelte @@ -67,6 +67,7 @@
{ diff --git a/src/lib/components/workspace/Models/SkillsSelector.svelte b/src/lib/components/workspace/Models/SkillsSelector.svelte index 69a31746f8..271aac79f1 100644 --- a/src/lib/components/workspace/Models/SkillsSelector.svelte +++ b/src/lib/components/workspace/Models/SkillsSelector.svelte @@ -58,6 +58,7 @@
{ if (e.detail === 'unchecked') { diff --git a/src/lib/components/workspace/Models/ToolsSelector.svelte b/src/lib/components/workspace/Models/ToolsSelector.svelte index e754087987..9fe8a9a1ba 100644 --- a/src/lib/components/workspace/Models/ToolsSelector.svelte +++ b/src/lib/components/workspace/Models/ToolsSelector.svelte @@ -56,6 +56,7 @@
{ if (e.detail === 'unchecked') { diff --git a/src/lib/components/workspace/common/AccessControl.svelte b/src/lib/components/workspace/common/AccessControl.svelte index f3cfa1ef6f..275d9e35b7 100644 --- a/src/lib/components/workspace/common/AccessControl.svelte +++ b/src/lib/components/workspace/common/AccessControl.svelte @@ -16,7 +16,7 @@ type AccessGrant = { id?: string; - principal_type: 'user' | 'group'; + principal_type: 'user' | 'group' | 'anyone'; principal_id: string; permission: 'read' | 'write'; }; @@ -34,6 +34,7 @@ export let share = true; export let sharePublic = true; + export let shareOpen = false; export let shareUsers = true; export let allowGroups = true; export let defaultPermission: 'read' | 'write' = 'read'; @@ -162,6 +163,14 @@ grant.principal_type === 'user' && grant.principal_id === '*' && grant.permission === 'read' ); + const hasAnyoneReadGrant = (grants: AccessGrant[]): boolean => + grants.some( + (grant) => + grant.principal_type === 'anyone' && + grant.principal_id === '*' && + grant.permission === 'read' + ); + const hasPublicWriteGrant = (grants: AccessGrant[]): boolean => grants.some( (grant) => @@ -170,16 +179,17 @@ grant.permission === 'write' ); - const currentGrants = (): AccessGrant[] => - Array.isArray(accessGrants) ? (accessGrants as AccessGrant[]) : []; + const currentGrants = (grants: AccessGrant[] | any = accessGrants): AccessGrant[] => + Array.isArray(grants) ? (grants as AccessGrant[]) : []; const getPrincipalIdsByPermission = ( principalType: 'user' | 'group', - permission: 'read' | 'write' + permission: 'read' | 'write', + grants: AccessGrant[] | any = accessGrants ): string[] => Array.from( new Set( - currentGrants() + currentGrants(grants) .filter( (grant) => grant.principal_type === principalType && grant.permission === permission ) @@ -188,7 +198,7 @@ ); const hasPrincipalGrant = ( - principalType: 'user' | 'group', + principalType: 'user' | 'group' | 'anyone', principalId: string, permission: 'read' | 'write' ): boolean => @@ -204,17 +214,32 @@ onChange(accessGrants); }; - const setPublic = (isPublic: boolean) => { - // Remove all user:* grants + const getVisibility = (grants: AccessGrant[]): 'private' | 'public' | 'open' => { + if (hasAnyoneReadGrant(grants)) return 'open'; + if (hasPublicReadGrant(grants)) return 'public'; + return 'private'; + }; + + const setVisibility = (visibility: 'private' | 'public' | 'open') => { const filtered = currentGrants().filter( - (grant) => !(grant.principal_type === 'user' && grant.principal_id === '*') + (grant) => + !( + (grant.principal_type === 'user' || grant.principal_type === 'anyone') && + grant.principal_id === '*' + ) ); - if (isPublic) { + if (visibility === 'public') { filtered.push({ principal_type: 'user', principal_id: '*', permission: 'read' }); + } else if (visibility === 'open') { + filtered.push({ + principal_type: 'anyone', + principal_id: '*', + permission: 'read' + }); } commitAccessGrants(filtered); }; @@ -237,7 +262,7 @@ }; const upsertPrincipalGrant = ( - principalType: 'user' | 'group', + principalType: 'user' | 'group' | 'anyone', principalId: string, permission: 'read' | 'write', grants: AccessGrant[] @@ -263,7 +288,7 @@ }; const removePrincipalGrant = ( - principalType: 'user' | 'group', + principalType: 'user' | 'group' | 'anyone', principalId: string, permission: 'read' | 'write', grants: AccessGrant[] @@ -277,14 +302,17 @@ ) ); - const removePrincipal = (principalType: 'user' | 'group', principalId: string) => { + const removePrincipal = (principalType: 'user' | 'group' | 'anyone', principalId: string) => { let next = [...currentGrants()]; next = removePrincipalGrant(principalType, principalId, 'read', next); next = removePrincipalGrant(principalType, principalId, 'write', next); commitAccessGrants(next); }; - const togglePrincipalWrite = (principalType: 'user' | 'group', principalId: string) => { + const togglePrincipalWrite = ( + principalType: 'user' | 'group' | 'anyone', + principalId: string + ) => { let next = [...currentGrants()]; const hasWrite = hasPrincipalGrant(principalType, principalId, 'write'); if (hasWrite) { @@ -379,12 +407,14 @@ $: if (readGroupIds.length > 0 || writeGroupIds.length > 0) { void ensureGroupsByIds([...readGroupIds, ...writeGroupIds]); } - $: readGroupIds = (accessGrants, getPrincipalIdsByPermission('group', 'read')); - $: writeGroupIds = (accessGrants, getPrincipalIdsByPermission('group', 'write')); - $: readUserIds = - (accessGrants, getPrincipalIdsByPermission('user', 'read').filter((id) => id !== '*')); - $: writeUserIds = - (accessGrants, getPrincipalIdsByPermission('user', 'write').filter((id) => id !== '*')); + $: readGroupIds = getPrincipalIdsByPermission('group', 'read', accessGrants); + $: writeGroupIds = getPrincipalIdsByPermission('group', 'write', accessGrants); + $: readUserIds = getPrincipalIdsByPermission('user', 'read', accessGrants).filter( + (id) => id !== '*' + ); + $: writeUserIds = getPrincipalIdsByPermission('user', 'write', accessGrants).filter( + (id) => id !== '*' + ); $: selectedUserIds = Array.from(new Set([...readUserIds, ...writeUserIds])); @@ -450,7 +480,7 @@
- {#if !hasPublicReadGrant(accessGrants ?? [])} + {#if getVisibility(accessGrants ?? []) === 'private'}
- {#if !hasPublicReadGrant(accessGrants ?? [])} + {#if getVisibility(accessGrants ?? []) === 'private'} {$i18n.t('Only select users and groups with permission can access')} - {:else} + {:else if getVisibility(accessGrants ?? []) === 'public'} {$i18n.t('Accessible to all users')} + {:else} + {$i18n.t('Anyone with the link can view')} {/if}
- {#if hasPublicReadGrant(accessGrants ?? []) && accessRoles.includes('write')} + {#if hasPublicReadGrant(accessGrants ?? []) && !hasAnyoneReadGrant(accessGrants ?? []) && accessRoles.includes('write')}
{$i18n.t('Allow public write access')} @@ -660,7 +695,7 @@ {/each} {/if} - {#if !hasPublicReadGrant(accessGrants ?? []) && accessGroups.length === 0 && selectedUsers.length === 0} + {#if getVisibility(accessGrants ?? []) === 'private' && accessGroups.length === 0 && selectedUsers.length === 0}
{$i18n.t('No access grants. Private to you.')}
diff --git a/src/lib/components/workspace/common/AccessControlModal.svelte b/src/lib/components/workspace/common/AccessControlModal.svelte index c03aa1fa40..3d67775a89 100644 --- a/src/lib/components/workspace/common/AccessControlModal.svelte +++ b/src/lib/components/workspace/common/AccessControlModal.svelte @@ -8,7 +8,7 @@ type AccessGrant = { id?: string; - principal_type: 'user' | 'group'; + principal_type: 'user' | 'group' | 'anyone'; principal_id: string; permission: 'read' | 'write'; }; @@ -20,6 +20,7 @@ export let share = true; export let sharePublic = true; + export let shareOpen = false; export let shareUsers = true; export let onChange = () => {}; @@ -49,6 +50,7 @@ {accessRoles} {share} {sharePublic} + {shareOpen} {shareUsers} />
diff --git a/src/lib/components/workspace/common/ValvesModal.svelte b/src/lib/components/workspace/common/ValvesModal.svelte index 254b758bb9..fc75607131 100644 --- a/src/lib/components/workspace/common/ValvesModal.svelte +++ b/src/lib/components/workspace/common/ValvesModal.svelte @@ -129,6 +129,9 @@ if (valvesSpec) { for (const property in valvesSpec.properties) { if (valvesSpec.properties[property]?.type === 'array') { + if (valvesSpec.properties[property]?.input?.type === 'multiselect') { + continue; + } if (valves[property] != null) { valves[property] = (Array.isArray(valves[property]) ? valves[property] : []).join( ',' diff --git a/src/lib/constants.ts b/src/lib/constants.ts index b25ec0f848..aacaa9fbca 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -108,6 +108,7 @@ export const DEFAULT_CAPABILITIES = { citations: true, status_updates: true, usage: undefined, + memory: true, builtin_tools: true }; diff --git a/src/lib/constants/permissions.ts b/src/lib/constants/permissions.ts index 25a618c79f..7eec950a50 100644 --- a/src/lib/constants/permissions.ts +++ b/src/lib/constants/permissions.ts @@ -29,6 +29,7 @@ export const DEFAULT_PERMISSIONS = { public_notes: false, folders: false, public_chats: false, + open_chats: false, public_calendars: false }, access_grants: { diff --git a/src/lib/i18n/locales/ar-BH/translation.json b/src/lib/i18n/locales/ar-BH/translation.json index 86f992a4b9..2852fd04ec 100644 --- a/src/lib/i18n/locales/ar-BH/translation.json +++ b/src/lib/i18n/locales/ar-BH/translation.json @@ -145,6 +145,7 @@ "Add to favorites": "", "Add User": "اضافة مستخدم", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -218,6 +219,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -251,6 +253,7 @@ "and create a new shared link.": "و أنشئ رابط مشترك جديد.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API الرابط الرئيسي", "API Key": "API مفتاح", @@ -316,6 +319,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -458,8 +462,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "المحادثات", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "تحقق مرة اخرى", "Check for updates": "تحقق من التحديثات", @@ -467,6 +474,7 @@ "Choose a model before saving...": "أختار موديل قبل الحفظ", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -500,6 +508,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -595,6 +604,7 @@ "Confirm": "", "Confirm Password": "تأكيد كلمة المرور", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -751,6 +761,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "الإفتراضي صلاحيات المستخدم", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -799,6 +810,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "لم أتبع التعليمات بشكل كامل", "Direct": "", @@ -870,6 +882,7 @@ "Download as SVG": "", "Download canceled": "تم اللغاء التحميل", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -917,6 +930,7 @@ "Edit Terminal Connection": "", "Edit User": "تعديل المستخدم", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -950,6 +964,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "ممكّن", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1215,6 +1230,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "فشل في حفظ المحادثة", "Failed to save models configuration": "", @@ -1282,6 +1298,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1329,6 +1346,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1507,6 +1525,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1580,9 +1599,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "يمكن أن تصدر بعض الأخطاء. لذلك يجب التحقق من المعلومات المهمة", "Loaded": "", "Loader": "", @@ -1621,6 +1640,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "مارس", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1693,7 +1714,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "تم تحميل النموذج '{{modelName}}' بنجاح", "Model '{{modelTag}}' is already in queue for downloading.": "النموذج '{{modelTag}}' موجود بالفعل في قائمة الانتظار للتحميل", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "نموذج {{modelName}} غير قادر على الرؤية", "Model {{name}} is now {{status}}": "نموذج {{name}} هو الآن {{status}}", @@ -1792,8 +1812,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1824,6 +1847,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1865,6 +1889,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1936,6 +1961,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "خطاء! أنت تستخدم طريقة غير مدعومة (الواجهة الأمامية فقط). يرجى تقديم واجهة WebUI من الواجهة الخلفية.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -2013,6 +2039,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2076,6 +2103,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2083,7 +2111,10 @@ "Previous 30 days": "أخر 30 يوم", "Previous 7 days": "أخر 7 أيام", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2225,6 +2256,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2233,6 +2265,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "النتيجة", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2281,6 +2314,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "البحث", @@ -2297,6 +2331,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2382,6 +2417,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "النموذج (النماذج) المحددة لا تدعم مدخلات الصور", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "تم", "Send a Message": "يُرجى إدخال طلبك هنا", @@ -2502,6 +2538,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2541,6 +2578,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "وقف التسلسل", @@ -2572,6 +2610,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2770,6 +2809,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2777,6 +2817,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "تحديث ونسخ الرابط", "Update Email": "", "Update embedding model": "", @@ -2834,6 +2875,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "مستخدم", @@ -2848,6 +2890,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2862,10 +2905,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "المتغير", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/ar/translation.json b/src/lib/i18n/locales/ar/translation.json index 9cadb2ae32..61f89fc118 100644 --- a/src/lib/i18n/locales/ar/translation.json +++ b/src/lib/i18n/locales/ar/translation.json @@ -145,6 +145,7 @@ "Add to favorites": "", "Add User": "إضافة مستخدم", "Add User Group": "إضافة مجموعة مستخدمين", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -218,6 +219,7 @@ "Allow User Location": "السماح بتحديد موقع المستخدم", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -251,6 +253,7 @@ "and create a new shared link.": "وإنشاء رابط مشترك جديد.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "الرابط الأساسي لواجهة API", "API Key": "مفتاح واجهة برمجة التطبيقات (API)", @@ -316,6 +319,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -458,8 +462,11 @@ "Chat Permissions": "أذونات المحادثة", "Chat Tags Auto-Generation": "الإنشاء التلقائي لطاچ المحادثة", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "المحادثات", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "تحقق مرة أخرى", "Check for updates": "تحقق من التحديثات", @@ -467,6 +474,7 @@ "Choose a model before saving...": "اختر نموذجًا قبل الحفظ...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -500,6 +508,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "مسح الذاكرة", "Clear Memory": "مسح الذاكرة", @@ -595,6 +604,7 @@ "Confirm": "تأكيد", "Confirm Password": "تأكيد كلمة المرور", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "أكد إجراءك", "Confirm your new password": "أكد كلمة مرورك الجديدة", "Confirm Your Password": "", @@ -751,6 +761,7 @@ "Default to ALL": "الافتراضي هو الكل", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "الإفتراضي صلاحيات المستخدم", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -799,6 +810,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "لم أتبع التعليمات بشكل كامل", "Direct": "", @@ -870,6 +882,7 @@ "Download as SVG": "تنزيل بصيغة SVG", "Download canceled": "تم اللغاء التحميل", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -917,6 +930,7 @@ "Edit Terminal Connection": "", "Edit User": "تعديل المستخدم", "Edit User Group": "تعديل مجموعة المستخدمين", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -950,6 +964,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "مفعل", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1215,6 +1230,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "فشل في حفظ المحادثة", "Failed to save models configuration": "فشل في حفظ إعدادات النماذج", @@ -1282,6 +1298,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1329,6 +1346,7 @@ "Generate an image": "توليد صورة", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1507,6 +1525,7 @@ "Keep in Sidebar": "", "Key": "المفتاح", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "المعرفة", "Knowledge Access": "الوصول إلى المعرفة", @@ -1580,9 +1599,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "جارٍ الاستماع...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "يمكن أن تصدر بعض الأخطاء. لذلك يجب التحقق من المعلومات المهمة", "Loaded": "", "Loader": "المحمّل", @@ -1621,6 +1640,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "مارس", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1693,7 +1714,6 @@ "Model": "النموذج", "Model '{{modelName}}' has been successfully downloaded.": "تم تحميل النموذج '{{modelName}}' بنجاح", "Model '{{modelTag}}' is already in queue for downloading.": "النموذج '{{modelTag}}' موجود بالفعل في قائمة الانتظار للتحميل", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "نموذج {{modelName}} غير قادر على الرؤية", "Model {{name}} is now {{status}}": "نموذج {{name}} هو الآن {{status}}", @@ -1792,8 +1812,11 @@ "New Webhook": "", "new-channel": "قناة جديدة", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1824,6 +1847,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1865,6 +1889,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "لم يتم العثور على مستخدمين.", "No valves": "", "No valves to update": "لا توجد صمامات للتحديث", @@ -1936,6 +1961,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "عذرًا! لا تزال بعض الملفات قيد الرفع. يرجى الانتظار حتى يكتمل الرفع.", "Oops! There was an error in the previous response.": "عذرًا! حدث خطأ في الرد السابق.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "خطاء! أنت تستخدم طريقة غير مدعومة (الواجهة الأمامية فقط). يرجى تقديم واجهة WebUI من الواجهة الخلفية.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -2013,6 +2039,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "تم رفض الإذن عند محاولة الوصول إلى أجهزة الوسائط", "Permission denied when accessing microphone": "تم رفض الإذن عند محاولة الوصول إلى الميكروفون", @@ -2076,6 +2103,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "معرف البادئة", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "يُستخدم معرف البادئة لتفادي التعارض مع الاتصالات الأخرى من خلال إضافة بادئة إلى معرفات النماذج – اتركه فارغًا لتعطيله", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2083,7 +2111,10 @@ "Previous 30 days": "أخر 30 يوم", "Previous 7 days": "أخر 7 أيام", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2225,6 +2256,7 @@ "Reset Vector Storage/Knowledge": "إعادة تعيين تخزين المتجهات/المعرفة", "Reset view": "إعادة تعيين العرض", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "لا يمكن تفعيل إشعارات الردود لأن صلاحيات الموقع مرفوضة. يرجى التوجه إلى إعدادات المتصفح لمنح الصلاحية اللازمة.", "Response Splitting": "", "Response Watermark": "", @@ -2233,6 +2265,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "النتيجة", "RESULT": "النتيجة", + "Retained Messages": "", "Retrieval": "الاسترجاع", "Retrieval Query Generation": "توليد استعلام الاسترجاع", "Retrieved {{count}} sources": "", @@ -2281,6 +2314,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "البحث", @@ -2297,6 +2331,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "مرشحات البحث", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2382,6 +2417,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "النموذج (النماذج) المحددة لا تدعم مدخلات الصور", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "تم", "Send a Message": "يُرجى إدخال طلبك هنا", @@ -2502,6 +2538,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2541,6 +2578,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "إيقاف", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "وقف التسلسل", @@ -2572,6 +2610,7 @@ "Support": "الدعم", "Support this plugin:": "دعم هذا المكون الإضافي:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2770,6 +2809,7 @@ "Unmute": "", "Unpin": "إزالة التثبيت", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2777,6 +2817,7 @@ "Untagged": "بدون وسوم", "Untitled": "", "Update": "تحديث", + "Update All Models": "", "Update and Copy Link": "تحديث ونسخ الرابط", "Update Email": "", "Update embedding model": "", @@ -2834,6 +2875,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "مستخدم", @@ -2848,6 +2890,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "اسم المستخدم", "Username Claim": "", @@ -2862,10 +2905,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "الصمامات", "Valves updated": "تم تحديث الصمامات", "Valves updated successfully": "تم تحديث الصمامات بنجاح", "variable": "المتغير", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/az-AZ/translation.json b/src/lib/i18n/locales/az-AZ/translation.json index d9602fbc78..54824b014e 100644 --- a/src/lib/i18n/locales/az-AZ/translation.json +++ b/src/lib/i18n/locales/az-AZ/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Favoritlərə əlavə et", "Add User": "İstifadəçi əlavə et", "Add User Group": "İstifadəçi qrupu əlavə et", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Veb səhifə əlavə et", "Add your Open Terminal URL and API key in Settings → Integrations.": "Ayarlar → İnteqrasiyalar bölməsində Open Terminal URL və API açarınızı əlavə edin.", @@ -190,6 +191,7 @@ "Allow User Location": "İstifadəçi məkanına icazə ver", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "və yeni paylaşım linki yaradın.", "Android": "Android", "Anyone": "Hər kəs", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Baza URL-i", "API Key": "API Açarı", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "Bilik bazasından fayl əlavə et", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Bilik əlavə et", "Attach Notes": "Qeydlər əlavə et", "Attach Webpage": "Veb səhifə əlavə et", @@ -430,8 +434,11 @@ "Chat Permissions": "Çat icazələri", "Chat Tags Auto-Generation": "Çat etiketlərinin avtomatik yaradılması", "Chat unshared successfully.": "Çatın paylaşımı uğurla ləğv edildi.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "çatlar", "Chats": "Çatlar", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Yenidən yoxla", "Check for updates": "Yeniləmələri yoxla", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Yadda saxlamazdan əvvəl bir model seçin...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Yaddaşı təmizlə", "Clear Memory": "Yaddaşı Təmizlə", @@ -563,6 +572,7 @@ "Confirm": "Təsdiqlə", "Confirm Password": "Şifrəni təsdiqlə", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Hərəkətinizi təsdiqləyin", "Confirm your new password": "Yeni şifrənizi təsdiqləyin", "Confirm Your Password": "Şifrənizi təsdiqləyin", @@ -719,6 +729,7 @@ "Default to ALL": "Standart olaraq HAMISI", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Fokuslanmış və müvafiq məzmun çıxarılması üçün standart olaraq seqmentləşdirilmiş axtarışdan istifadə edin; bu, əksər hallar üçün tövsiyə olunur.", + "Default Upload Mode": "", "Default User Role": "Standart istifadəçi rolu", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Artefaktları avtomatik müəyyən et", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktə et", "Didn't fully follow instructions": "Təlimatlara tam əməl etmədi", "Direct": "Birbaşa", @@ -838,6 +850,7 @@ "Download as SVG": "SVG kimi yüklə", "Download canceled": "Yükləmə ləğv edildi", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Terminal bağlantısını redaktə et", "Edit User": "İstifadəçini redaktə et", "Edit User Group": "İstifadəçi qrupunu redaktə et", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "workflow.json məzmununu redaktə et", "edited": "redaktə edildi", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Model tərəfindən istifadə olunan mühakimə (reasoning) etiketlərini aktivləşdirin, söndürün və ya fərdiləşdirin. \"Aktivdir\" standart etiketlərdən istifadə edir, \"Söndürülüb\" mühakimə etiketlərini bağlayır, \"Fərdi\" isə öz başlanğıc və son etiketlərinizi təyin etməyə imkan verir.", "Enabled": "Aktivdir", + "End call": "", "End Tag": "Son etiketi", "Endpoint": "", "Endpoint URL": "Son nöqtə (Endpoint) URL-i", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Üzv çıxarıla bilmədi", "Failed to render diagram": "Diaqram yaradılmadı", "Failed to render visualization": "Vizuallaşdırma yaradılmadı", + "Failed to save chat variables": "", "Failed to save connections": "Bağlantılar yadda saxlanılmadı", "Failed to save conversation": "Söhbət yadda saxlanılmadı", "Failed to save models configuration": "Modellərin konfiqurasiyası yadda saxlanılmadı", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Qovluq uğurla yeniləndi", "Folders": "Qovluqlar", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Davam sualı", "Follow Up Generation": "Davam suallarının yaradılması", "Follow Up Generation Prompt": "Davam sualı yaratma göstərişi", @@ -1289,6 +1306,7 @@ "Generate an image": "Şəkil yarat", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Şəkillər yaradın və redaktə edin", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Mesaj cütü yarat", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Yan paneldə saxla", "Key": "Açar", "Key is required": "Açar tələb olunur", + "key_name": "", "Keyboard": "", "Knowledge": "Bilik", "Knowledge Access": "Bilik bazasına giriş", @@ -1540,9 +1559,9 @@ "List": "Siyahı", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Dinlənilir...", + "LiteLLM": "", "Live": "Canlı", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Süni intellekt (LLM) səhv edə bilər. Vacib məlumatları yoxlayın.", "Loaded": "", "Loader": "Yükləyici", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mart", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown başlıq mətni bölücüsü", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' modeli uğurla yükləndi.", "Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' modeli artıq yükləmə növbəsindədir.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "{{modelName}} modeli görüntünü tanıma (vision) qabiliyyətinə malik deyil", "Model {{name}} is now {{status}}": "{{name}} modeli indi {{status}} statusundadır", @@ -1752,8 +1772,11 @@ "New Webhook": "Yeni Webhook", "new-channel": "yeni-kanal", "Next message": "Növbəti mesaj", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Giriş icazəsi yoxdur. Sizin üçün özəldir.", "No actions found": "", "No activity data": "Fəaliyyət məlumatı yoxdur", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "Bu bilik bazasında fayl yoxdur.", "No files yet. Upload files or run Python code to create them.": "Hələ ki fayl yoxdur. Fayl yükləyin və ya yaratmaq üçün Python kodu icra edin.", "No filters found": "", + "No folders": "", "No functions found": "Funksiya tapılmadı", "No groups found": "Qrup tapılmadı", "No history available": "Tarixçə yoxdur", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Alət tapılmadı", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "İstifadəçi tapılmadı.", "No valves": "Klapan (valve) yoxdur", "No valves to update": "Yenilənəcək klapan yoxdur", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Vay! Fayllar hələ də yüklənir. Zəhmət olmasa yükləmənin tamamlanmasını gözləyin.", "Oops! There was an error in the previous response.": "Vay! Əvvəlki cavabda bir xəta baş verdi.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Vay! Siz dəstəklənməyən bir üsuldan istifadə edirsiniz (yalnız frontend). Zəhmət olmasa WebUI-ni backend-dən işə salın.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Gözləyən istifadəçi örtük məzmunu", "Pending User Overlay Title": "Gözləyən istifadəçi örtük başlığı", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Media cihazlarına giriş zamanı icazə rədd edildi", "Permission denied when accessing microphone": "Mikrofona giriş zamanı icazə rədd edildi", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefiks ID-si", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefiks ID model ID-lərinə prefiks əlavə edərək digər bağlantılarla ziddiyyətlərin qarşısını almaq üçün istifadə olunur - söndürmək üçün boş saxlayın", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Fayl yaradılmasının qarşısını al", "Preview": "Önizləmə", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Son 30 gün", "Previous 7 days": "Son 7 gün", "Previous message": "Əvvəlki mesaj", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Özəl", "Private conversation between selected users": "Seçilmiş istifadəçilər arasında özəl söhbət", "Production version updated": "İstehsalat (Production) versiyası yeniləndi", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Vektor yaddaşını/Biliyi sıfırla", "Reset view": "Görünüşü sıfırla", "Response": "Cavab", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Veb sayt icazələri rədd edildiyi üçün cavab bildirişləri aktivləşdirilə bilməz. Zəhmət olmasa, lazımi girişi təmin etmək üçün brauzer ayarlarınıza daxil olun.", "Response Splitting": "", "Response Watermark": "Cavab su nişanı", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Nəticə", "RESULT": "NƏTİCƏ", + "Retained Messages": "", "Retrieval": "Məlumatın gətirilməsi (Retrieval)", "Retrieval Query Generation": "Məlumat gətirmə sorğusunun yaradılması", "Retrieved {{count}} sources": "{{count}} mənbə gətirildi", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Şaxə dəyişdikdə sürüşdür", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Axtar", @@ -2245,6 +2279,7 @@ "Search Files": "Faylları axtar", "Search filters": "", "Search Filters": "Filtrləri axtar", + "Search folders": "", "search for archived chats": "arxivləşdirilmiş çatları axtar", "search for folders": "qovluqları axtar", "search for pinned chats": "bərkidilmiş çatları axtar", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "Seçilmiş model: {{modelName}}", "Selected model(s) do not support image inputs": "Seçilmiş model(lər) şəkil girişini dəstəkləmir", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantik", "Send": "Göndər", "Send a Message": "Mesaj Göndər", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "Bacarıqların ictimai paylaşımı", "Skills Sharing": "Bacarıqların paylaşılması", "Skip Cache": "Keşi atla", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Xəta baş verdi :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Addımlar", "Stop": "Dayandır", + "Stop camera": "", "Stop Download": "Yükləməni dayandır", "Stop Generating": "Generasiyanı dayandır", "Stop Sequence": "Dayandırma ardıcıllığı", @@ -2516,6 +2554,7 @@ "Support": "Dəstək", "Support this plugin:": "Bu plagini dəstəkləyin:", "Supported MIME Types": "Dəstəklənən MIME növləri", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "Sinxronizasiya", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Sabitlənmişdən çıxar", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Çatı paylaşımı dayandır", @@ -2721,6 +2761,7 @@ "Untagged": "Etiketsiz", "Untitled": "Adsız", "Update": "Yenilə", + "Update All Models": "", "Update and Copy Link": "Yenilə və linki kopyala", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "istifadəçi", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "İstifadəçi reytinqləri (bəyənmə/bəyənməmə)", "User Status": "İstifadəçi statusu", + "User Variables": "", "User Webhooks": "İstifadəçi Webhook-ları", "Username": "İstifadəçi adı", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves (Klapanlar)", "Valves updated": "Valves yeniləndi", "Valves updated successfully": "Valves uğurla yeniləndi", "variable": "dəyişən", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Bağlantını yoxla", "Verify SSL Certificate": "SSL Sertifikatını yoxla", diff --git a/src/lib/i18n/locales/bg-BG/translation.json b/src/lib/i18n/locales/bg-BG/translation.json index 2a4beae1b4..97b1badab8 100644 --- a/src/lib/i18n/locales/bg-BG/translation.json +++ b/src/lib/i18n/locales/bg-BG/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Добавяне на потребител", "Add User Group": "Добавяне на потребителска група", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Разреши местоположението на потребителя", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "и създай нов общ линк.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Базов URL", "API Key": "API Ключ", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Разрешения за чат", "Chat Tags Auto-Generation": "Автоматично генериране на тагове за чат", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Чатове", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Проверете Още Веднъж", "Check for updates": "Проверка за актуализации", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Изберете модел преди запазване...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Изчистване на паметта", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "Потвърди", "Confirm Password": "Потвърди Парола", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Потвърдете действието си", "Confirm your new password": "Потвърдете новата си парола", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "По подразбиране за ВСИЧКИ", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Ролята на потребителя по подразбиране", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Не следва напълно инструкциите", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "Изтегляне като SVG", "Download canceled": "Изтегляне отменено", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Редактиране на потребител", "Edit User Group": "Редактиране на потребителска група", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Активирано", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Неуспешно запазване на разговора", "Failed to save models configuration": "Неуспешно запазване на конфигурацията на моделите", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "Генериране на изображение", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Ключ", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Знания", "Knowledge Access": "Достъп до знания", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Слушане...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs могат да правят грешки. Проверете важните данни.", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Март", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Модел", "Model '{{modelName}}' has been successfully downloaded.": "Моделът '{{modelName}}' беше успешно свален.", "Model '{{modelTag}}' is already in queue for downloading.": "Моделът '{{modelTag}}' е вече в очакване за сваляне.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Моделът {{modelName}} не поддържа визуални възможности", "Model {{name}} is now {{status}}": "Моделът {{name}} сега е {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "нов-канал", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Не са намерени потребители.", "No valves": "", "No valves to update": "Няма клапани за актуализиране", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Упс! Все още има файлове, които се качват. Моля, изчакайте качването да приключи.", "Oops! There was an error in the previous response.": "Упс! Имаше грешка в предишния отговор.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Упс! Използвате неподдържан метод (само фронтенд). Моля, сервирайте WebUI от бекенда.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Отказан достъп при опит за достъп до медийни устройства", "Permission denied when accessing microphone": "Отказан достъп при опит за достъп до микрофона", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Префикс ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Префикс ID се използва за избягване на конфликти с други връзки чрез добавяне на префикс към ID-тата на моделите - оставете празно, за да деактивирате", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Предишните 30 дни", "Previous 7 days": "Предишните 7 дни", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Нулиране на векторното хранилище/знания", "Reset view": "Нулиране на изгледа", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Известията за отговори не могат да бъдат активирани, тъй като разрешенията за уебсайта са отказани. Моля, посетете настройките на вашия браузър, за да дадете необходимия достъп.", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Резултат", "RESULT": "Резултат", + "Retained Messages": "", "Retrieval": "Извличане", "Retrieval Query Generation": "Генериране на заявка за извличане", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Търси", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Филтри за търсене", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Избраният(те) модел(и) не поддържа въвеждане на изображения", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Изпрати", "Send a Message": "Изпращане на Съобщение", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Спри", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Стоп последователност", @@ -2516,6 +2554,7 @@ "Support": "Поддръжка", "Support this plugin:": "Подкрепете този плъгин:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Откачи", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Без етикет", "Untitled": "Неозаглавен", "Update": "Актуализиране", + "Update All Models": "", "Update and Copy Link": "Обнови и копирай връзката", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "потребител", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Потребителско име", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Клапани", "Valves updated": "Клапаните са актуализирани", "Valves updated successfully": "Клапаните са актуализирани успешно", "variable": "променлива", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/bn-BD/translation.json b/src/lib/i18n/locales/bn-BD/translation.json index a214e25d83..1ec0ccebf3 100644 --- a/src/lib/i18n/locales/bn-BD/translation.json +++ b/src/lib/i18n/locales/bn-BD/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "ইউজার যোগ করুন", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "এবং একটি নতুন শেয়ারে লিংক তৈরি করুন.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "এপিআই বেজ ইউআরএল", "API Key": "এপিআই কোড", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "চ্যাটসমূহ", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "আবার চেক করুন", "Check for updates": "নতুন আপডেট আছে কিনা চেক করুন", @@ -439,6 +446,7 @@ "Choose a model before saving...": "সেভ করার আগে একটি মডেল নির্বাচন করুন", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "পাসওয়ার্ড নিশ্চিত করুন", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "ইউজারের ডিফল্ট পদবি", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "ইনস্ট্রাকশন সম্পূর্ণ অনুসরণ করা হয়নি", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "ডাউনলোড বাতিল করা হয়েছে", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "ইউজার এডিট করুন", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "সক্রিয়", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "কথোপকথন সংরক্ষণ করতে ব্যর্থ", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM ভুল করতে পারে। গুরুত্বপূর্ণ তথ্য যাচাই করে নিন।", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "মার্চ", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' মডেল সফলভাবে ডাউনলোড হয়েছে।", "Model '{{modelTag}}' is already in queue for downloading.": "{{modelTag}} ডাউনলোডের জন্য আগে থেকেই অপেক্ষমান আছে।", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "মডেল {{modelName}} দৃষ্টি সক্ষম নয়", "Model {{name}} is now {{status}}": "মডেল {{name}} এখন {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "আপনি একটা আনসাপোর্টেড পদ্ধতি (শুধু ফ্রন্টএন্ড) ব্যবহার করছেন। দয়া করে WebUI ব্যাকএন্ড থেকে চালনা করুন।", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "পূর্ব ৩০ দিন", "Previous 7 days": "পূর্ব ৭ দিন", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "ফলাফল", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "অনুসন্ধান", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "নির্বাচিত মডেল(গুলি) চিত্র ইনপুট সমর্থন করে না", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "পাঠান", "Send a Message": "একটি মেসেজ পাঠান", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "সিকোয়েন্স থামান", @@ -2516,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "আপডেট এবং লিংক কপি করুন", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "ব্যবহারকারী", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "ভেরিয়েবল", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/bo-TB/translation.json b/src/lib/i18n/locales/bo-TB/translation.json index 13e770a17b..8ea191cdd5 100644 --- a/src/lib/i18n/locales/bo-TB/translation.json +++ b/src/lib/i18n/locales/bo-TB/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "", "Add User": "བེད་སྤྱོད་མཁན་སྣོན་པ།", "Add User Group": "བེད་སྤྱོད་མཁན་ཚོགས་པ་སྣོན་པ།", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -183,6 +184,7 @@ "Allow User Location": "བེད་སྤྱོད་མཁན་གནས་ཡུལ་ལ་གནང་བ་སྤྲོད་པ།", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "དང་མཉམ་སྤྱོད་སྦྲེལ་ཐག་གསར་པ་ཞིག་བཟོ་བ།", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API གཞི་རྩའི་ URL", "API Key": "API ལྡེ་མིག", @@ -281,6 +284,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -423,8 +427,11 @@ "Chat Permissions": "ཁ་བརྡའི་དབང་ཚད།", "Chat Tags Auto-Generation": "ཁ་བརྡའི་རྟགས་རང་འགུལ་བཟོ་སྐྲུན།", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "ཁ་བརྡ།", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "ཡང་བསྐྱར་ཞིབ་དཔྱད།", "Check for updates": "གསར་སྒྱུར་འཚོལ་ཞིབ།", @@ -432,6 +439,7 @@ "Choose a model before saving...": "ཉར་ཚགས་མ་བྱས་སྔོན་དུ་དཔེ་དབྱིབས་ཤིག་གདམ་པ།...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "དྲན་ཤེས་གཙང་སེལ།", "Clear Memory": "དྲན་ཤེས་གཙང་སེལ།", @@ -555,6 +564,7 @@ "Confirm": "གཏན་འཁེལ།", "Confirm Password": "གསང་གྲངས་གཏན་འཁེལ།", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "ཁྱེད་ཀྱི་བྱ་སྤྱོད་གཏན་འཁེལ།", "Confirm your new password": "ཁྱེད་ཀྱི་གསང་གྲངས་གསར་པ་གཏན་འཁེལ།", "Confirm Your Password": "", @@ -711,6 +721,7 @@ "Default to ALL": "སྔོན་སྒྲིག་ཏུ་ཡོངས་རྫོགས།", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "དམིགས་ཚད་དང་འབྲེལ་ཡོད་ནང་དོན་འདོན་སྤེལ་གྱི་ཆེད་དུ་སྔོན་སྒྲིག་ཏུ་དུམ་བུ་ལེན་ཚུར་སྒྲུབ་བྱེད་པ། འདི་ནི་གནས་སྟངས་མང་ཆེ་བའི་ཆེད་དུ་འོས་སྦྱོར་བྱེད།", + "Default Upload Mode": "", "Default User Role": "སྔོན་སྒྲིག་བེད་སྤྱོད་མཁན་གྱི་གནས་ཚད།", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "ལམ་སྟོན་ཡོངས་སུ་མ་བསྒྲུབས།", "Direct": "ཐད་ཀར།", @@ -830,6 +842,7 @@ "Download as SVG": "SVG ཐོག་ཕབ་ལེན།", "Download canceled": "ཕབ་ལེན་རྩིས་མེད་བཏང་།", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "", "Edit User": "བེད་སྤྱོད་མཁན་ཞུ་དག", "Edit User Group": "བེད་སྤྱོད་མཁན་ཚོགས་པ་ཞུ་དག", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "སྒུལ་བསྐྱོད་བྱས་ཡོད།", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1165,6 +1180,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "གླེང་མོལ་ཉར་ཚགས་བྱེད་མ་ཐུབ།", "Failed to save models configuration": "དཔེ་དབྱིབས་སྒྲིག་འགོད་ཉར་ཚགས་བྱེད་མ་ཐུབ།", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1279,6 +1296,7 @@ "Generate an image": "པར་ཞིག་བཟོ་བ།", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "", "Key": "ལྡེ་མིག", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "ཤེས་བྱ།", "Knowledge Access": "ཤེས་བྱར་འཛུལ་སྤྱོད།", @@ -1530,9 +1549,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "ཉན་བཞིན་པ།...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs ལ་ནོར་འཁྲུལ་ཡོང་སྲིད། གནས་ཚུལ་གལ་ཆེན་ར་སྤྲོད་བྱེད་རོགས།", "Loaded": "", "Loader": "ནང་འཇུག་བྱེད་པོ།", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "ཟླ་བ་གསུམ་པ།", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "དཔེ་དབྱིབས།", "Model '{{modelName}}' has been successfully downloaded.": "དཔེ་དབྱིབས། '{{modelName}}' ལེགས་པར་ཕབ་ལེན་བྱས་ཟིན།", "Model '{{modelTag}}' is already in queue for downloading.": "དཔེ་དབྱིབས། '{{modelTag}}' ཕབ་ལེན་གྱི་སྒུག་ཐོ་ནང་ཡོད་ཟིན།", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "དཔེ་དབྱིབས། {{modelName}} ལ་མཐོང་ནུས་མེད།", "Model {{name}} is now {{status}}": "དཔེ་དབྱིབས། {{name}} ད་ལྟ་ {{status}} ཡིན།", @@ -1742,8 +1762,11 @@ "New Webhook": "", "new-channel": "བགྲོ་གླེང་གསར་པ།", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1815,6 +1839,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "བེད་སྤྱོད་མཁན་མ་རྙེད།", "No valves": "", "No valves to update": "གསར་སྒྱུར་བྱེད་རྒྱུའི་ Valve མེད།", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "ཨོའོ། ད་དུང་སྤར་བཞིན་པའི་ཡིག་ཆ་ཡོད། སྤར་ཚར་བར་སྒུག་རོགས།", "Oops! There was an error in the previous response.": "ཨོའོ། ལན་སྔ་མར་ནོར་འཁྲུལ་ཞིག་བྱུང་སོང་།", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "ཨོའོ། ཁྱེད་ཀྱིས་རྒྱབ་སྐྱོར་མེད་པའི་ཐབས་ལམ་ཞིག་ (མདུན་ངོས་ཁོ་ན།) བེད་སྤྱོད་གཏོང་བཞིན་འདུག རྒྱབ་སྣེ་ནས་ WebUI མཁོ་སྤྲོད་བྱེད་རོགས།", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "བརྒྱུད་ལམ་སྒྲིག་ཆས་འཛུལ་སྤྱོད་སྐབས་དབང་ཚད་ཁས་མ་བླངས།", "Permission denied when accessing microphone": "སྐད་སྒྲ་འཛིན་ཆས་འཛུལ་སྤྱོད་སྐབས་དབང་ཚད་ཁས་མ་བླངས།", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "སྔོན་སྦྱོར་ ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "སྔོན་སྦྱོར་ ID ནི་དཔེ་དབྱིབས་ཀྱི་ IDs ལ་སྔོན་སྦྱོར་ཞིག་སྣོན་ནས་སྦྲེལ་མཐུད་གཞན་དང་གདོང་ཐུག་ལས་གཡོལ་བར་བེད་སྤྱོད་བྱེད། - ནུས་མེད་བཏང་བར་སྟོང་པ་བཞག་པ།", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2033,7 +2061,10 @@ "Previous 30 days": "ཉིན་ ༣༠ སྔོན་མ།", "Previous 7 days": "ཉིན་ ༧ སྔོན་མ།", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "སྒེར།", "Private conversation between selected users": "", "Production version updated": "", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "ཚད་བརྡའི་གསོག་ཆས།/ཤེས་བྱ་སླར་སྒྲིག", "Reset view": "མཐོང་སྣང་སླར་སྒྲིག", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "དྲ་ཚིགས་ཀྱི་དབང་ཚད་ཁས་མ་བླངས་པས་ལན་གྱི་བརྡ་ཁྱབ་སྒུལ་བསྐྱོད་བྱེད་མི་ཐུབ། དགོས་ངེས་ཀྱི་འཛུལ་སྤྱོད་སྤྲོད་པར་ཁྱེད་ཀྱི་བརྡ་འཚོལ་ཆས་ཀྱི་སྒྲིག་འགོད་ལ་ལྟ་རོགས།", "Response Splitting": "", "Response Watermark": "", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "འབྲས་བུ།", "RESULT": "འབྲས་བུ།", + "Retained Messages": "", "Retrieval": "ལེན་ཚུར་སྒྲུབ།", "Retrieval Query Generation": "ལེན་ཚུར་སྒྲུབ་འདྲི་བ་བཟོ་སྐྲུན།", "Retrieved {{count}} sources": "", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "འཚོལ་བཤེར།", @@ -2232,6 +2266,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "འཚོལ་བཤེར་འཚག་མ།", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "གདམ་ཟིན་པའི་དཔེ་དབྱིབས་(ཚོ)ས་པར་གྱི་ནང་འཇུག་ལ་རྒྱབ་སྐྱོར་མི་བྱེད།", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "གཏོང་བ།", "Send a Message": "འཕྲིན་ཞིག་གཏོང་བ།", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "མཚམས་འཇོག", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "མཚམས་འཇོག་རིམ་པ།", @@ -2502,6 +2540,7 @@ "Support": "རྒྱབ་སྐྱོར།", "Support this plugin:": "plugin འདི་ལ་རྒྱབ་སྐྱོར་བྱེད་པ།:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2700,6 +2739,7 @@ "Unmute": "", "Unpin": "ཕྱིར་འདོན།", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2707,6 +2747,7 @@ "Untagged": "རྟགས་མེད།", "Untitled": "", "Update": "གསར་སྒྱུར།", + "Update All Models": "", "Update and Copy Link": "གསར་སྒྱུར་དང་སྦྲེལ་ཐག་འདྲ་བཤུས།", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "བེད་སྤྱོད་མཁན།", @@ -2778,6 +2820,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "བེད་སྤྱོད་མཁན་གྱི་ Webhooks", "Username": "བེད་སྤྱོད་མིང་།", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves གསར་སྒྱུར་བྱས།", "Valves updated successfully": "Valves ལེགས་པར་གསར་སྒྱུར་བྱས།", "variable": "འགྱུར་ཚད།", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "སྦྲེལ་མཐུད་ར་སྤྲོད།", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/bs-BA/translation.json b/src/lib/i18n/locales/bs-BA/translation.json index 6808930b5a..f177ac6161 100644 --- a/src/lib/i18n/locales/bs-BA/translation.json +++ b/src/lib/i18n/locales/bs-BA/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Dodaj korisnika", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Dozvoli User Lokacije", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "i stvorite novu dijeljenu vezu.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Osnovni URL API-ja", "API Key": "API ključ", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Prikazi znanje", "Attach Notes": "Prikazi zapise", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Razgovori", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Provjeri ponovo", "Check for updates": "Provjeri za ažuriranja", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Odaberite model prije spremanja...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Očisti memoriju", "Clear Memory": "", @@ -571,6 +580,7 @@ "Confirm": "Potvrdi", "Confirm Password": "Potvrdite lozinku", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Potvrdi radnju", "Confirm your new password": "Potvrdi novu sifru", "Confirm Your Password": "Potvrdi sifru", @@ -727,6 +737,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Zadana korisnička uloga", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Nije u potpunosti slijedio upute", "Direct": "", @@ -846,6 +858,7 @@ "Download as SVG": "", "Download canceled": "Preuzimanje otkazano", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Uredi korisnika", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Omogućeno", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Neuspješno spremanje razgovora", "Failed to save models configuration": "", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1299,6 +1316,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Znanje", "Knowledge Access": "", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Slušam...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM-ovi mogu pogriješiti. Provjerite važne informacije.", "Loaded": "", "Loader": "", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mart", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' je uspješno preuzet.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' je već u redu za preuzimanje.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} ne čita vizualne impute", "Model {{name}} is now {{status}}": "Model {{name}} sada je {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Koristite nepodržanu metodu (samo frontend). Molimo poslužite WebUI s backend-a.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Dopuštenje je odbijeno prilikom pristupa medijskim uređajima", "Permission denied when accessing microphone": "Dopuštenje je odbijeno prilikom pristupa mikrofonu", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Prethodnih 30 dana", "Previous 7 days": "Prethodnih 7 dana", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "REZULTAT", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Pretraga", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Odabrani modeli ne podržavaju unose slika", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Pošalji", "Send a Message": "Pošaljite poruku", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Zaustavi sekvencu", @@ -2530,6 +2568,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "Ažuriraj i kopiraj vezu", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "korisnik", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "varijabla", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/ca-ES/translation.json b/src/lib/i18n/locales/ca-ES/translation.json index 2034e55584..582b2bff13 100644 --- a/src/lib/i18n/locales/ca-ES/translation.json +++ b/src/lib/i18n/locales/ca-ES/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "Afegir als favorits", "Add User": "Afegir un usuari", "Add User Group": "Afegir grup d'usuaris", + "Add User Variable": "", "Add webhook": "Afegeix un webhook", "Add webpage": "Afegir pàgina web", "Add your Open Terminal URL and API key in Settings → Integrations.": "Afegeix l'URL i la clau API de l'Open Terminal a Configuració → Integracions.", @@ -197,6 +198,7 @@ "Allow User Location": "Permetre la ubicació de l'usuari", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "i crear un nou enllaç compartit.", "Android": "Android", "Anyone": "Algú", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Base de l'API", "API Key": "clau API", @@ -295,6 +298,7 @@ "At time of event": "Al moment de l'esdeveniment", "Attach File From Knowledge": "Adjuntar arxiu del coneixement", "Attach Files": "Adjuntar arxius", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Adjuntar coneixement", "Attach Notes": "Adjuntar notes", "Attach Webpage": "Adjuntar pàgina web", @@ -437,8 +441,11 @@ "Chat Permissions": "Permisos del xat", "Chat Tags Auto-Generation": "Generació automàtica d'etiquetes del xat", "Chat unshared successfully.": "El xat s'ha deixat de compartir correctament", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "xats", "Chats": "Xats", + "Chats Open Sharing": "", "Chats Public Sharing": "Compartició pública dels xats", "Check Again": "Comprovar-ho de nou", "Check for updates": "Comprovar si hi ha actualitzacions", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Triar un model abans de desar...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Esborrar la memòria", "Clear Memory": "Esborrar la memòria", @@ -571,6 +580,7 @@ "Confirm": "Confirmar", "Confirm Password": "Confirmar la contrasenya", "Confirm Prompt from Embed": "Confirmar el prompt des de la incrustació", + "Confirm recording": "", "Confirm your action": "Confirma la teva acció", "Confirm your new password": "Confirma la teva nova contrasenya", "Confirm Your Password": "Confirma la teva contrasenya", @@ -727,6 +737,7 @@ "Default to ALL": "Per defecte TOTS", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Per defecte, Segmented Retrieval per a l'extracció de contingut rellevant, es recomana en la majoria dels casos.", + "Default Upload Mode": "", "Default User Role": "Rol d'usuari per defecte", "Default webhook": "Webhook predeterminat", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "Deseleccionar", "Detect Artifacts Automatically": "Detectar automàticament els artefactes", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dictar", "Didn't fully follow instructions": "No s'han seguit les instruccions completament", "Direct": "Directe", @@ -846,6 +858,7 @@ "Download as SVG": "Descarrega com a SVG", "Download canceled": "Descàrrega cancel·lada", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "Editar la connexió al terminal", "Edit User": "Editar l'usuari", "Edit User Group": "Editar el grup d'usuaris", + "Edit User Variable": "", "Edit webhook": "Edita el webhook", "Edit workflow.json content": "Editar el contingut de workflow.json", "edited": "editat", @@ -926,6 +940,7 @@ "Enable Web Search": "Activa la cerca web", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Activar, desactivar o personalitzar les etiquetes de raonament que utilitza el model. \"Activat\" utilitza etiquetes predeterminades, \"Desactivat\" desactiva les etiquetes de raonament i \"Personalitzat\" permet especificar les etiquetes d'inici i finalització.", "Enabled": "Habilitat", + "End call": "", "End Tag": "Etiqueta de finalització", "Endpoint": "Punt final", "Endpoint URL": "URL de connexió", @@ -1185,6 +1200,7 @@ "Failed to remove member": "No s'ha pogut eliminar el membre", "Failed to render diagram": "No s'ha pogut renderitzar el diagrama", "Failed to render visualization": "No s'ha pogut renderitzar la visualització", + "Failed to save chat variables": "", "Failed to save connections": "No s'han pogut desar les connexions", "Failed to save conversation": "No s'ha pogut desar la conversa", "Failed to save models configuration": "No s'ha pogut desar la configuració dels models", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "Carpeta actualitzada correctament", "Folders": "Carpetes", "Folders Sharing": "Compartició de carpetes", + "Follow assistant responses as they are generated.": "", "Follow up": "Seguir", "Follow Up Generation": "Generació d'indicacions de continuació", "Follow Up Generation Prompt": "Indicació per a la generació d'indicacions de continuació", @@ -1299,6 +1316,7 @@ "Generate an image": "Generar una imatge", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Generar i editar imatges", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Generar parella de missatges", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Mantenir a la barra lateral", "Key": "Clau", "Key is required": "La clau és necessària", + "key_name": "", "Keyboard": "", "Knowledge": "Coneixement", "Knowledge Access": "Accés al coneixement", @@ -1550,9 +1569,9 @@ "List": "Llista", "List calendars, search, create, update, and delete calendar events": "Llistar calendaris, cercar, crear, actualitzar i suprimir esdeveniments de calendari", "Listening...": "Escoltant...", + "LiteLLM": "", "Live": "Live", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Els models de llenguatge poden cometre errors. Verifica la informació important.", "Loaded": "Carregat", "Loader": "Carregador", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "Font mapejada", "March": "Març", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Divisor de text de capçalera de Markdown", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "El model '{{modelName}}' s'ha descarregat correctament.", "Model '{{modelTag}}' is already in queue for downloading.": "El model '{{modelTag}}' ja està en cua per ser descarregat.", - "Model {{modelId}} not found": "Model {{modelId}} no trobat", "Model {{modelName}} deleted successfully": "El model {{modelName}} s'ha eliminat correctament", "Model {{modelName}} is not vision capable": "El model {{modelName}} no és capaç de visió", "Model {{name}} is now {{status}}": "El model {{name}} ara és {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "Nou webhook", "new-channel": "nou-canal", "Next message": "Missatge següent", + "Next month": "", "Next page": "", "Next run": "Següent execució", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Sense permisos d'accés. Privat per a tu.", "No actions found": "", "No activity data": "No hi ha dades d'activitat", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "No hi ha arxius a la base de coneixement.", "No files yet. Upload files or run Python code to create them.": "Encara no hi ha fitxers. Puja fitxers o executa codi Python per crear-los.", "No filters found": "", + "No folders": "", "No functions found": "No s'han trobat funcions", "No groups found": "No s'han trobat grups", "No history available": "No hi ha historial disponible", @@ -1835,6 +1859,7 @@ "No tools accessible": "No hi ha eines accessibles", "No tools found": "No s'han trobat eines", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "No s'han trobat usuaris", "No valves": "No hi ha valves", "No valves to update": "No hi ha cap Valve per actualitzar", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ui! Encara hi ha fitxers pujant-se. Si us plau, espera que finalitzi la càrrega.", "Oops! There was an error in the previous response.": "Ui! Hi ha hagut un error a la resposta anterior.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ui! Estàs utilitzant un mètode no suportat (només frontend). Si us plau, serveix la WebUI des del backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "Comptes pendents", "Pending User Overlay Content": "Contingut de la finestra d'usuari pendent", "Pending User Overlay Title": "Títol de la finestra d'usuari pendent", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Permís denegat en accedir a dispositius multimèdia", "Permission denied when accessing microphone": "Permís denegat en accedir al micròfon", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Identificador del prefix", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "L'identificador de prefix s'utilitza per evitar conflictes amb altres connexions afegint un prefix als ID de model; deixa'l en blanc per desactivar-lo.", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Prevenir la creació d'arxius", "Preview": "Previsualització", @@ -2053,7 +2081,10 @@ "Previous 30 days": "30 dies anteriors", "Previous 7 days": "7 dies anteriors", "Previous message": "Missatge anterior", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privat", "Private conversation between selected users": "Conversa privada entre usuaris seleccionats", "Production version updated": "S'ha actualitzat la versió en producció", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Restableix el Repositori de vectors/Coneixement", "Reset view": "Netejar la vista", "Response": "Resposta", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notificacions de resposta no es poden activar perquè els permisos del lloc web han estat rebutjats. Comprova les preferències del navegador per donar l'accés necessari.", "Response Splitting": "", "Response Watermark": "Marca d'aigua de la resposta", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultat", "RESULT": "Resultat", + "Retained Messages": "", "Retrieval": "Retrieval", "Retrieval Query Generation": "Generació de consultes Retrieval", "Retrieved {{count}} sources": "S'han obtingut {{count}} fonts", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "La data d'execucuió ha de ser en el futur", "Scopes": "Àmbits", "Scroll On Branch Change": "Fer scroll en canviar de branca", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Anar a dalt", "Search": "Cercar", @@ -2258,6 +2292,7 @@ "Search Files": "Cerca arxius", "Search filters": "Filtres de cerca", "Search Filters": "Filtres de cerca", + "Search folders": "", "search for archived chats": "cercar xats arxivats", "search for folders": "cercar carpetes", "search for pinned chats": "cercar xats marcats", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "Model seleccionat: {{modelName}}", "Selected model(s) do not support image inputs": "El(s) model(s) seleccionats no admeten l'entrada d'imatges", + "Selected models define incompatible Chat Variables.": "", "semantic": "semàntic", "Send": "Enviar", "Send a Message": "Enviar un missatge", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "Compartició pública de les habilitats", "Skills Sharing": "Compartició de les habilitats", "Skip Cache": "Ometre la memòria cau", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Quelcom no ha anat bé", "Sonar": "Sonar", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Passos", "Stop": "Atura", + "Stop camera": "", "Stop Download": "Aturar la descàrrega", "Stop Generating": "Aturar la generació", "Stop Sequence": "Atura la seqüència", @@ -2530,6 +2568,7 @@ "Support": "Dona suport", "Support this plugin:": "Dona suport a aquest complement:", "Supported MIME Types": "Tipus MIME admesos", + "Switch camera": "", "Switch to JSON editor": "Canviar a l'editor JSON", "Switch to visual editor": "Canviar a l'editor visual", "Sync": "Sincronitzar", @@ -2728,6 +2767,7 @@ "Unmute": "No silenciar", "Unpin": "Alliberar", "Unpin from Sidebar": "No fixis a la barra lateral", + "Unread": "", "Unshare All": "Deixa de compartir-ho tot", "Unshare All Shared Chats": "Deixa de compartir tots els xats compartits", "Unshare Chat": "Deixar de compartir el xat", @@ -2735,6 +2775,7 @@ "Untagged": "Sense etiquetes", "Untitled": "Sense títol", "Update": "Actualitzar", + "Update All Models": "", "Update and Copy Link": "Actualitzar i copiar l'enllaç", "Update Email": "Correu electrònic d'actualització", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "Utilitzar la cerca web?", "user": "usuari", @@ -2806,6 +2848,7 @@ "User Preview": "Previsualitzar l'usuari", "User ratings (thumbs up/down)": "Valoracions dels usuaris (polze amunt/avall)", "User Status": "Estats d'usuari", + "User Variables": "", "User Webhooks": "Webhooks d'usuari", "Username": "Nom d'usuari", "Username Claim": "Reclamació de nom d'usuari", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves actualitzades", "Valves updated successfully": "Valves actualitzades correctament", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "Camp vectorial", "Verify Connection": "Verificar la connexió", "Verify SSL Certificate": "Verificar el certificat SSL", diff --git a/src/lib/i18n/locales/ceb-PH/translation.json b/src/lib/i18n/locales/ceb-PH/translation.json index 8e453c37c6..8363be69a9 100644 --- a/src/lib/i18n/locales/ceb-PH/translation.json +++ b/src/lib/i18n/locales/ceb-PH/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Base URL", "API Key": "yawe sa API", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Mga panaghisgot", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Susiha pag-usab", "Check for updates": "Susiha ang mga update", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Pagpili og template sa dili pa i-save...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "Kumpirma ang password", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Default nga Papel sa Gumagamit", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "I-edit ang tiggamit", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Gipaandar", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Napakyas sa pagtipig sa panag-istorya", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "Ang mga LLM mahimong masayop. ", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "Ang modelo'{{modelName}}' malampuson nga na-download.", "Model '{{modelTag}}' is already in queue for downloading.": "Ang modelo'{{modelTag}}' naa na sa pila para ma-download.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "", "Model {{name}} is now {{status}}": "", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! ", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "", "Previous 7 days": "", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "RESULTA", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Pagpanukiduki", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "", "Send a Message": "Magpadala ug mensahe", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Pagkasunod-sunod sa pagsira", @@ -2516,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "tiggamit", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/cs-CZ/translation.json b/src/lib/i18n/locales/cs-CZ/translation.json index 58fe450352..600d521e4b 100644 --- a/src/lib/i18n/locales/cs-CZ/translation.json +++ b/src/lib/i18n/locales/cs-CZ/translation.json @@ -131,6 +131,7 @@ "Add to favorites": "", "Add User": "Přidat uživatele", "Add User Group": "Přidat skupinu uživatelů", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -204,6 +205,7 @@ "Allow User Location": "Povolit zjištění polohy uživatele", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -237,6 +239,7 @@ "and create a new shared link.": "a vytvořit nový sdílený odkaz.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Základní URL adresa API", "API Key": "Klíč API", @@ -302,6 +305,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Připojit znalosti", "Attach Notes": "Přiojit poznámky", "Attach Webpage": "Připojit web", @@ -444,8 +448,11 @@ "Chat Permissions": "Oprávnění konverzace", "Chat Tags Auto-Generation": "Automatické generování štítků konverzace", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Konverzace", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Zkontrolovat znovu", "Check for updates": "Zkontrolovat aktualizace", @@ -453,6 +460,7 @@ "Choose a model before saving...": "Před uložením vyberte model...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -486,6 +494,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Vymazat paměť", "Clear Memory": "Vymazat paměť", @@ -579,6 +588,7 @@ "Confirm": "Potvrdit", "Confirm Password": "Potvrdit heslo", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Potvrďte svou akci", "Confirm your new password": "Potvrďte své nové heslo", "Confirm Your Password": "Potvrďte své heslo", @@ -735,6 +745,7 @@ "Default to ALL": "Výchozí hodnota VŠE", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Výchozí je segmentované vyhledávání pro cílenou a relevantní extrakci obsahu, což se doporučuje ve většině případů.", + "Default Upload Mode": "", "Default User Role": "Výchozí role uživatele", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -783,6 +794,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Automaticky detekovat artefakty", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktovat", "Didn't fully follow instructions": "Nedodržel plně pokyny", "Direct": "Přímé", @@ -854,6 +866,7 @@ "Download as SVG": "Stáhnout jako SVG", "Download canceled": "Stahování zrušeno", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -901,6 +914,7 @@ "Edit Terminal Connection": "", "Edit User": "Upravit uživatele", "Edit User Group": "Upravit skupinu uživatelů", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -934,6 +948,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Povoleno", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "URL koncového bodu", @@ -1195,6 +1210,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Nepodařilo se uložit připojení", "Failed to save conversation": "Nepodařilo se uložit konverzaci", "Failed to save models configuration": "Nepodařilo se uložit konfiguraci modelů", @@ -1262,6 +1278,7 @@ "Folder updated successfully": "Složka byla úspěšně aktualizována", "Folders": "Složky", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Následná otázka", "Follow Up Generation": "Generování následných otázek", "Follow Up Generation Prompt": "Pokyn pro generování následných instrukcí", @@ -1309,6 +1326,7 @@ "Generate an image": "Generovat obrázek", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1487,6 +1505,7 @@ "Keep in Sidebar": "Ponechat v postranním panelu", "Key": "Klíč", "Key is required": "Klíč je vyžadován", + "key_name": "", "Keyboard": "", "Knowledge": "Znalosti", "Knowledge Access": "Přístup ke znalostem", @@ -1560,9 +1579,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Poslouchám...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM mohou dělat chyby. Ověřte si důležité informace.", "Loaded": "", "Loader": "Zavaděč", @@ -1601,6 +1620,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Březen", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1673,7 +1694,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' byl úspěšně stažen.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' je již ve frontě na stažení.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} nemá schopnost zpracování obrazu.", "Model {{name}} is now {{status}}": "Model {{name}} je nyní {{status}}.", @@ -1772,8 +1792,11 @@ "New Webhook": "", "new-channel": "novy-kanal", "Next message": "Další zpráva", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1804,6 +1827,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "Žádné funkce nenalezeny", "No groups found": "", "No history available": "", @@ -1845,6 +1869,7 @@ "No tools accessible": "", "No tools found": "Nebyly nalezeny žádné nástroje", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Nebyli nalezeni žádní uživatelé.", "No valves": "Žádné valves", "No valves to update": "Žádné valves k aktualizaci", @@ -1916,6 +1941,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Jejda! Některé soubory se stále nahrávají. Počkejte prosím na dokončení nahrávání.", "Oops! There was an error in the previous response.": "Jejda! V předchozí odpovědi došlo k chybě.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Jejda! Používáte nepodporovanou metodu (pouze frontend). Spusťte prosím WebUI z backendu.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1993,6 +2019,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Obsah překryvné vrstvy pro čekajícího uživatele", "Pending User Overlay Title": "Název překryvné vrstvy pro čekajícího uživatele", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Přístup k mediálním zařízením byl odepřen", "Permission denied when accessing microphone": "Přístup k mikrofonu byl odepřen", @@ -2056,6 +2083,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID se používá k zamezení konfliktů s jinými připojeními přidáním prefixu k ID modelů - pro vypnutí ponechte prázdné", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Náhled", @@ -2063,7 +2091,10 @@ "Previous 30 days": "Posledních 30 dní", "Previous 7 days": "Posledních 7 dní", "Previous message": "Předchozí zpráva", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Soukromé", "Private conversation between selected users": "", "Production version updated": "", @@ -2201,6 +2232,7 @@ "Reset Vector Storage/Knowledge": "Resetovat vektorové úložiště/znalosti", "Reset view": "Resetovat zobrazení", "Response": "Odpověď", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Oznámení o odpovědích nelze aktivovat, protože oprávnění webu byla zamítnuta. Navštivte nastavení svého prohlížeče a udělte potřebný přístup.", "Response Splitting": "", "Response Watermark": "Vodoznak odpovědi", @@ -2209,6 +2241,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Výsledek", "RESULT": "Výsledek", + "Retained Messages": "", "Retrieval": "Vyhledávání", "Retrieval Query Generation": "Generování vyhledávacího dotazu", "Retrieved {{count}} sources": "", @@ -2255,6 +2288,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Posouvat při změně větve", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Hledat", @@ -2271,6 +2305,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Filtry vyhledávání", + "Search folders": "", "search for archived chats": "hledat archivované konverzace", "search for folders": "hledat složky", "search for pinned chats": "hledat připnuté konverzace", @@ -2356,6 +2391,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Vybraný model (modely) nepodporuje obrazové vstupy.", + "Selected models define incompatible Chat Variables.": "", "semantic": "sémantický", "Send": "Odeslat", "Send a Message": "Odeslat zprávu", @@ -2476,6 +2512,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Přeskočit mezipaměť", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Něco se pokazilo :/", "Sonar": "Sonar", @@ -2513,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Zastavit", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "stop sequence", @@ -2544,6 +2582,7 @@ "Support": "Podpora", "Support this plugin:": "Podpořte tento plugin:", "Supported MIME Types": "Podporované typy MIME", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2742,6 +2781,7 @@ "Unmute": "", "Unpin": "Odepnout", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2749,6 +2789,7 @@ "Untagged": "Bez štítku", "Untitled": "Bez názvu", "Update": "Aktualizovat", + "Update All Models": "", "Update and Copy Link": "Aktualizovat a zkopírovat odkaz", "Update Email": "", "Update embedding model": "", @@ -2806,6 +2847,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "uživatel", @@ -2820,6 +2862,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Uživatelské webhooky", "Username": "Uživatelské jméno", "Username Claim": "", @@ -2834,10 +2877,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves aktualizovány", "Valves updated successfully": "Valves byly úspěšně aktualizovány.", "variable": "proměnná", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Ověřit připojení", "Verify SSL Certificate": "Ověřit SSL certifikát", diff --git a/src/lib/i18n/locales/da-DK/translation.json b/src/lib/i18n/locales/da-DK/translation.json index e6098e0ebe..d589c334df 100644 --- a/src/lib/i18n/locales/da-DK/translation.json +++ b/src/lib/i18n/locales/da-DK/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Tilføj bruger", "Add User Group": "Tilføj Brugergruppe", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Tillad bruger-lokation", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "og lav et nyt link til deling", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API base URL", "API Key": "API nøgle", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "Vedhæft fil fra viden", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Vedhæft viden", "Attach Notes": "Vedhæft noter", "Attach Webpage": "Vedhæft webside", @@ -430,8 +434,11 @@ "Chat Permissions": "Chat tilladelser", "Chat Tags Auto-Generation": "Chat tags automatisk generering", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Tjek igen", "Check for updates": "Søg efter opdateringer", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Vælg en model før du gemmer", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Slet hukommelse", "Clear Memory": "Slet hukommelse", @@ -563,6 +572,7 @@ "Confirm": "Bekræft", "Confirm Password": "Bekræft password", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Bekræft din handling", "Confirm your new password": "Bekræft dit nye password", "Confirm Your Password": "Bekræft dit password", @@ -719,6 +729,7 @@ "Default to ALL": "Standard til ALLE", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Standard til segmenteret hentning for fokuseret og relevant indholdsudtrækning, dette anbefales i de fleste tilfælde.", + "Default Upload Mode": "", "Default User Role": "Brugers rolle som standard", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Genkend artifakter automatisk", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dikter", "Didn't fully follow instructions": "Fulgte ikke instruktioner", "Direct": "Direkte", @@ -838,6 +850,7 @@ "Download as SVG": "Download som SVG", "Download canceled": "Download afbrudt", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Rediger bruger", "Edit User Group": "Rediger brugergruppe", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Rediger workflow.json indhold", "edited": "redigeret", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Aktiver, deaktiver eller tilpas brugerdefinerede ræsonneringstags benyttet af modellen. \"Aktiveret\" benytter standardtags, \"Deaktiveret\" slår ræsonneringstags fra og \"Brugerdefineret\" giver dig mulighed for at angive dine egne start- og sluttags", "Enabled": "Aktiveret", + "End call": "", "End Tag": "Slut tag", "Endpoint": "", "Endpoint URL": "Endpoint URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Kunne ikke fjerne medlem", "Failed to render diagram": "Kunne ikke rendere diagram", "Failed to render visualization": "Kunne ikke rendere visualisering", + "Failed to save chat variables": "", "Failed to save connections": "Kunne ikke gemme forbindelser", "Failed to save conversation": "Kunne ikke gemme samtalen", "Failed to save models configuration": "Kunne ikke gemme modeller konfiguration", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Mappe opdateret", "Folders": "Mapper", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Opfølgning", "Follow Up Generation": "Opfølgnings generering", "Follow Up Generation Prompt": "Opfølgnings genererings prompt", @@ -1289,6 +1306,7 @@ "Generate an image": "Generer et billede", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Generer besked par", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Behold i sidebaren", "Key": "Nøgle", "Key is required": "Nøgle er påkrævet", + "key_name": "", "Keyboard": "", "Knowledge": "Viden", "Knowledge Access": "Videnadgang", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Lytter...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM'er kan lave fejl. Bekræft vigtige oplysninger.", "Loaded": "", "Loader": "Loader", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marts", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' er blevet downloadet.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' er allerede i kø til download.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} understøtter ikke billeder", "Model {{name}} is now {{status}}": "Model {{name}} er nu {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "ny-kanal", "Next message": "Næste besked", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "Ingen funktioner fundet", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Ingen værktøjer fundet", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Ingen brugere blev fundet.", "No valves": "Ingen ventiler", "No valves to update": "Ingen ventiler at opdatere", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ups! Der er filer, der stadig uploades. Vent, til uploaden er færdig.", "Oops! There was an error in the previous response.": "Ups! Der var en fejl i det tidligere svar.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Du bruger en metode, der ikke understøttes (kun frontend). Kør WebUI fra backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Afventende bruger overlay indhold", "Pending User Overlay Title": "Afventende bruger overlay titel", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Tilladelse nægtet ved adgang til medieenheder", "Permission denied when accessing microphone": "Tilladelse nægtet ved adgang til mikrofon", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID bruges til at undgå konflikter med andre forbindelser ved at tilføje et prefix til model-ID'erne - lad være tom for at deaktivere", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Forhindr filoprettelse", "Preview": "Forhåndsvisning", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Seneste 30 dage", "Previous 7 days": "Seneste 7 dage", "Previous message": "Forrige besked", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privat", "Private conversation between selected users": "Privat samtale mellem valgte brugere", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Nulstil vektor lager/viden", "Reset view": "Nulstil visning", "Response": "Svar", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Svarnotifikationer kan ikke aktiveres, da webstedets tilladelser er blevet nægtet. Besøg dine browserindstillinger for at give den nødvendige adgang.", "Response Splitting": "", "Response Watermark": "Vandmærke på svar", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultat", "RESULT": "Resultat", + "Retained Messages": "", "Retrieval": "Hentning", "Retrieval Query Generation": "Hentnings forespørgsel generering", "Retrieved {{count}} sources": "Fandt en kildehenvisning", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Scroll ved gren ændring", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Søg", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Søg i filtre", + "Search folders": "", "search for archived chats": "søg efter arkiverede chats", "search for folders": "søg efter mapper", "search for pinned chats": "søg efter fastgjorte chats", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Valgte model(ler) understøtter ikke billedinput", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantisk", "Send": "Send", "Send a Message": "Send en besked", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Spring cache over", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Noget gik galt :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Trin", "Stop": "Stop", + "Stop camera": "", "Stop Download": "", "Stop Generating": "Stop generering", "Stop Sequence": "Stopsekvens", @@ -2516,6 +2554,7 @@ "Support": "Support", "Support this plugin:": "Støt dette plugin:", "Supported MIME Types": "Understøttede MIME-typer", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Frigør", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Uden mærker", "Untitled": "Unavngivet", "Update": "Opdater", + "Update All Models": "", "Update and Copy Link": "Opdater og kopier link", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "bruger", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Bruger Webhooks", "Username": "Brugernavn", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Ventiler", "Valves updated": "Ventiler opdateret", "Valves updated successfully": "Ventiler opdateret.", "variable": "variabel", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Verificer forbindelse", "Verify SSL Certificate": "Verificer SSL-certifikat", diff --git a/src/lib/i18n/locales/de-DE/translation.json b/src/lib/i18n/locales/de-DE/translation.json index 6a0d22d808..40fe77dda1 100644 --- a/src/lib/i18n/locales/de-DE/translation.json +++ b/src/lib/i18n/locales/de-DE/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Zu Favoriten hinzufügen", "Add User": "Benutzer hinzufügen", "Add User Group": "Benutzergruppe hinzufügen", + "Add User Variable": "", "Add webhook": "Webhook hinzufügen", "Add webpage": "Webseite hinzufügen", "Add your Open Terminal URL and API key in Settings → Integrations.": "Füge deine Open Terminal URL und API Key in den Einstellungen → Integrationen hinzu.", @@ -190,6 +191,7 @@ "Allow User Location": "Standortzugriff erlauben", "Allow users to access calendar features.": "Erlaubt Benutzern die Nutzung der Kalenderfunktionen.", "Allow users to authenticate with an LDAP directory.": "Erlaubt Benutzern die Anmeldung über ein LDAP-Verzeichnis.", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "Erlaubt Benutzern, Webhooks in ihrem Konto einzurichten.", "Allow users to create accounts through OAuth.": "Erlaubt Benutzern, Konten über OAuth zu erstellen.", "Allow users to create and manage notes.": "Erlaubt Benutzern, Notizen zu erstellen und zu verwalten.", @@ -223,6 +225,7 @@ "and create a new shared link.": "und erstellen Sie einen neuen Freigabe-Link.", "Android": "Android", "Anyone": "Jeder", + "Anyone with the link can view": "", "API Auth String": "API-Authentifizierungsstring", "API Base URL": "API-Basis-URL", "API Key": "API-Schlüssel", @@ -288,6 +291,7 @@ "At time of event": "Zum Zeitpunkt des Ereignisses", "Attach File From Knowledge": "Datei aus Wissensspeicher anhängen", "Attach Files": "Dateien anhängen", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Wissen anhängen", "Attach Notes": "Notizen anhängen", "Attach Webpage": "Webseite anhängen", @@ -430,8 +434,11 @@ "Chat Permissions": "Chat-Berechtigungen", "Chat Tags Auto-Generation": "Automatische Chat-Tag-Generierung", "Chat unshared successfully.": "Chat-Freigabe erfolgreich aufgehoben", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "Chats", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "Öffentliche Chat-Freigabe", "Check Again": "Erneut prüfen", "Check for updates": "Nach Updates suchen", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Wählen Sie vor dem Speichern ein Modell...", "Choose automatic, left-to-right, or right-to-left text flow.": "Wählt automatischen Textfluss oder feste Ausrichtung von links nach rechts bzw. von rechts nach links.", "Choose fallback models for background tasks. Current Model follows the active chat model.": "Wählen Sie Ersatzmodelle für Hintergrundaufgaben. \"Aktuelles Modell\" übernimmt das im Chat aktive Modell.", + "Choose folder": "", "Choose how extracted text is split before indexing.": "Legt fest, wie extrahierter Text vor der Indexierung aufgeteilt wird.", "Choose how uploaded documents are parsed before indexing.": "Legt fest, wie hochgeladene Dokumente vor der Indexierung verarbeitet werden.", "Choose how web result pages are fetched and read.": "Legt fest, wie Ergebnisseiten aus dem Web abgerufen und ausgelesen werden.", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "Claim, der als URL des Profilbilds verwendet wird.", "Claim used as the stable user identifier.": "Claim, der als dauerhafte Benutzerkennung verwendet wird.", "Claim used as the user email address.": "Claim, der als E-Mail-Adresse des Benutzers verwendet wird.", + "Clear": "", "Clear filters to reorder": "Filter zurücksetzen, um die Reihenfolge zu ändern", "Clear memory": "Alle Erinnerungen löschen", "Clear Memory": "Alle Erinnerungen löschen", @@ -563,6 +572,7 @@ "Confirm": "Bestätigen", "Confirm Password": "Passwort bestätigen", "Confirm Prompt from Embed": "Bestätige den Prompt, den das Embed senden will", + "Confirm recording": "", "Confirm your action": "Bitte bestätigen", "Confirm your new password": "Neues Passwort bestätigen", "Confirm Your Password": "Passwort bestätigen", @@ -719,6 +729,7 @@ "Default to ALL": "Standardmäßig ALLE", "Default to memberOf": "Standardmäßig memberOf", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Standardmäßig segmentierter Abruf für fokussierte Inhaltsextraktion (empfohlen).", + "Default Upload Mode": "", "Default User Role": "Standard-Benutzerrolle", "Default webhook": "Standard-Webhook", "Defines the behavior used for spoken conversations.": "Legt das Verhalten für gesprochene Unterhaltungen fest.", @@ -767,6 +778,7 @@ "Deselect": "Abwählen", "Detect Artifacts Automatically": "Artefakte automatisch erkennen", "Detect generated artifacts and show them in the artifact workspace.": "Erkennt generierte Artefakte und zeigt sie im Artefakte-Bereich an.", + "Detected Variables": "", "Dictate": "Diktieren", "Didn't fully follow instructions": "Anweisungen nicht vollständig befolgt", "Direct": "Direkt", @@ -838,6 +850,7 @@ "Download as SVG": "Als SVG herunterladen", "Download canceled": "Download abgebrochen", "Download every user's chat history as JSON.": "Lädt den Chatverlauf aller Benutzer als JSON herunter.", + "Download failed": "", "Download the application database when supported.": "Lädt die Datenbank der Anwendung herunter, sofern unterstützt.", "Download the current admin configuration as JSON.": "Lädt die aktuelle Administrationskonfiguration als JSON herunter.", "Download your chat history as a JSON export.": "Lädt Ihren Chatverlauf als JSON-Export herunter.", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Terminal Verbindung bearbeiten", "Edit User": "Benutzer bearbeiten", "Edit User Group": "Benutzergruppe bearbeiten", + "Edit User Variable": "", "Edit webhook": "Webhook bearbeiten", "Edit workflow.json content": "workflow.json Inhalt bearbeiten", "edited": "bearbeitet", @@ -918,6 +932,7 @@ "Enable Web Search": "Websuche aktivieren", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Aktivieren, deaktivieren oder passen Sie Reasoning-Tags an. \"Aktiviert\" nutzt Standard-Tags, \"Deaktiviert\" schaltet sie aus, \"Benutzerdefiniert\" erlaubt eigene Start/End-Tags.", "Enabled": "Aktiviert", + "End call": "", "End Tag": "End-Tag", "Endpoint": "Endpunkt", "Endpoint URL": "Endpunkt-URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Mitglied konnte nicht entfernt werden", "Failed to render diagram": "Diagramm konnte nicht gerendert werden", "Failed to render visualization": "Visualisierung konnte nicht gerendert werden", + "Failed to save chat variables": "", "Failed to save connections": "Verbindungen konnten nicht gespeichert werden", "Failed to save conversation": "Unterhaltung konnte nicht gespeichert werden", "Failed to save models configuration": "Modellkonfiguration konnte nicht gespeichert werden", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Ordner erfolgreich aktualisiert", "Folders": "Ordner", "Folders Sharing": "Ordnerfreigabe", + "Follow assistant responses as they are generated.": "Scrollt automatisch mit, während die Antwort des Assistenten erzeugt wird.", "Follow up": "Folgefragen", "Follow Up Generation": "Folgefragen-Generierung", "Follow Up Generation Prompt": "Prompt für Folgefragen-Generierung", @@ -1257,7 +1274,6 @@ "Format Markdown in previews and compact content surfaces.": "Stellt Markdown in Vorschauen und kompakten Ansichten formatiert dar.", "Format Markdown syntax in assistant responses.": "Stellt Markdown in Antworten des Assistenten formatiert dar.", "Format Markdown syntax in your own messages.": "Stellt Markdown in Ihren eigenen Nachrichten formatiert dar.", - "Follow assistant responses as they are generated.": "Scrollt automatisch mit, während die Antwort des Assistenten erzeugt wird.", "Formatting may be inconsistent from source.": "Formatierung kann von der Quelle abweichen.", "Forward": "Weiterleiten", "Forwards system user OAuth access token to authenticate": "Leitet OAuth-Zugriffstoken des Systembenutzers zur Authentifizierung weiter", @@ -1290,6 +1306,7 @@ "Generate an image": "Ein Bild generieren", "Generate an image prompt before sending the request.": "Erzeugt vor dem Senden der Anfrage einen Bild-Prompt.", "Generate and edit images": "Generiere und bearbeite Bilder", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "Erzeugt Chat-Titel automatisch aus dem Inhalt der Unterhaltung.", "Generate Message Pair": "Nachrichtenpaar generieren", "Generate suggested follow-up prompts after responses.": "Erzeugt nach Antworten Vorschläge für Folgefragen.", @@ -1468,6 +1485,7 @@ "Keep in Sidebar": "In Seitenleiste anzeigen", "Key": "Schlüssel", "Key is required": "Schlüssel ist erforderlich", + "key_name": "", "Keyboard": "Tastatur", "Knowledge": "Wissen", "Knowledge Access": "Wissenszugriff", @@ -1541,9 +1559,9 @@ "List": "Liste", "List calendars, search, create, update, and delete calendar events": "Kalender auflisten, suchen, erstellen, aktualisieren und löschen", "Listening...": "Höre zu...", + "LiteLLM": "", "Live": "Live", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "KI-Modelle können Fehler machen. Überprüfen Sie wichtige Informationen.", "Loaded": "geladen", "Loader": "Loader", @@ -1582,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "Ordnet die Workflow-Node-Eingaben für die Bildgenerierung zu.", "Mapped Source": "Zugeordnete Quelle", "March": "März", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown-Header-Text-Splitter", "Max background": "Max. im Hintergrund", @@ -1654,7 +1674,6 @@ "Model": "Modell", "Model '{{modelName}}' has been successfully downloaded.": "Modell '{{modelName}}' wurde erfolgreich heruntergeladen.", "Model '{{modelTag}}' is already in queue for downloading.": "Modell '{{modelTag}}' befindet sich bereits in der Warteschlange.", - "Model {{modelId}} not found": "Modell {{modelId}} nicht gefunden", "Model {{modelName}} deleted successfully": "Modell {{modelName}} erfolgreich gelöscht", "Model {{modelName}} is not vision capable": "Das Modell {{modelName}} unterstützt keine Bilderkennung", "Model {{name}} is now {{status}}": "Modell {{name}} ist jetzt {{status}}", @@ -1753,8 +1772,11 @@ "New Webhook": "Neuer Webhook", "new-channel": "neuer-kanal", "Next message": "Nächste Nachricht", + "Next month": "", "Next page": "Nächste Seite", "Next run": "Nächster Durchlauf", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Keine Freigaben konfiguriert. Nur für Sie zugänglich.", "No actions found": "Keine Aktionen gefunden", "No activity data": "Keine Aktivitätsdaten", @@ -1785,6 +1807,7 @@ "No files in this knowledge base.": "Keine Dateien in diesem Wissensspeicher", "No files yet. Upload files or run Python code to create them.": "Noch keine Dateien. Lad Dateien hoch oder lass Python code laufen um welche zu erstellen.", "No filters found": "Keine Filter gefunden", + "No folders": "", "No functions found": "Keine Funktionen gefunden", "No groups found": "Keine Gruppen gefunden", "No history available": "Keine History verfügbar", @@ -1826,6 +1849,7 @@ "No tools accessible": "Keine Werkzeuge zugänglich", "No tools found": "Keine Werkzeuge gefunden", "No usage data found": "Keine Nutzungsdaten gefunden", + "No user variables configured.": "", "No users were found.": "Keine Benutzer gefunden.", "No valves": "Keine Valves", "No valves to update": "Keine Valves zum Aktualisieren", @@ -1897,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ups! Es werden noch Dateien hochgeladen. Bitte warten Sie, bis der Upload abgeschlossen ist.", "Oops! There was an error in the previous response.": "Ups! Es gab einen Fehler in der vorherigen Antwort.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Sie verwenden eine nicht unterstützte Methode (nur Frontend). Bitte stellen Sie die WebUI über das Backend bereit.", + "Open": "", "Open automation": "Automatisierung öffnen", "Open create menu": "Menü \"Erstellen\" öffnen", "Open detail blocks by default.": "Klappt Detailblöcke standardmäßig auf.", @@ -1974,6 +1999,7 @@ "Pending Accounts": "Ausstehende Konten", "Pending User Overlay Content": "Inhalt des Overlays 'Ausstehende Kontoaktivierung'", "Pending User Overlay Title": "Titel des Overlays 'Ausstehende Kontoaktivierung'", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "Löscht nach Bestätigung alle Chats endgültig.", "Permission denied when accessing media devices": "Zugriff auf Mediengeräte verweigert", "Permission denied when accessing microphone": "Zugriff auf Mikrofon verweigert", @@ -2037,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "Bevorzugte Sprachcodes für Transkripte, durch Kommas getrennt.", "Prefix ID": "Präfix-ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Die Präfix-ID wird verwendet, um Konflikte mit anderen Verbindungen zu vermeiden, indem ein Präfix zu den Modell-IDs hinzugefügt wird - zum Deaktivieren leer lassen.", + "Preparing download...": "", "Press keys...": "Tasten drücken...", "Prevent File Creation": "Dateierstellung verhindern", "Preview": "Vorschau", @@ -2044,7 +2071,10 @@ "Previous 30 days": "Letzte 30 Tage", "Previous 7 days": "Letzte 7 Tage", "Previous message": "Vorherige Nachricht", + "Previous month": "", "Previous page": "Vorherige Seite", + "Previous slide": "", + "Previous version": "", "Private": "Privat", "Private conversation between selected users": "Private Unterhaltung zwischen ausgewählten Benutzern", "Production version updated": "Produktiv-Version updated", @@ -2187,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "Beschränkt Domains anhand einer kommagetrennten Liste oder schließt sie aus.", "Result": "Ergebnis", "RESULT": "ERGEBNIS", + "Retained Messages": "", "Retrieval": "Abruf", "Retrieval Query Generation": "Abfrage-Generierung", "Retrieved {{count}} sources": "{{count}} Quellen abgerufen", @@ -2231,6 +2262,7 @@ "Scheduled time must be in the future": "Geplante Zeit muss in der Zukunft liegen", "Scopes": "Scopes", "Scroll On Branch Change": "Bei Zweigwechsel scrollen", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "Springt beim Wechsel zwischen Antwortzweigen zum aktiven Zweig.", "Scroll to Top": "Zum Anfang scrollen", "Search": "Suchen", @@ -2247,6 +2279,7 @@ "Search Files": "Suche Dateien", "Search filters": "Filter durchsuchen", "Search Filters": "Suchfilter", + "Search folders": "", "search for archived chats": "nach archivierten Chats suchen", "search for folders": "nach Ordnern suchen", "search for pinned chats": "nach angehefteten Chats suchen", @@ -2332,6 +2365,7 @@ "Selected": "Ausgewählt", "Selected model: {{modelName}}": "Ausgewähltes Modell: {{modelName}}", "Selected model(s) do not support image inputs": "Die ausgewählten Modelle unterstützen keine Bildeingaben", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantisch", "Send": "Senden", "Send a Message": "Eine Nachricht senden", @@ -2452,6 +2486,7 @@ "Skills Public Sharing": "Öffentliches Teilen von Skills", "Skills Sharing": "Teilen von Skills", "Skip Cache": "Cache überspringen", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "Überspringt zwischengespeicherte Marker-Ergebnisse und führt die Verarbeitung erneut aus.", "Something went wrong :/": "Etwas ist schiefgelaufen :/", "Sonar": "Sonar", @@ -2487,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Schritte", "Stop": "Stopp", + "Stop camera": "", "Stop Download": "Download stoppen", "Stop Generating": "Generierung stoppen", "Stop Sequence": "Stoppsequenz", @@ -2518,6 +2554,7 @@ "Support": "Unterstützung", "Support this plugin:": "Unterstützen Sie dieses Plugin:", "Supported MIME Types": "Unterstützte MIME-Typen", + "Switch camera": "", "Switch to JSON editor": "Zum JSON-Editor wechseln", "Switch to visual editor": "Zum visuellen Editor wechseln", "Sync": "Synchronisieren", @@ -2716,6 +2753,7 @@ "Unmute": "Stummschalten aufheben", "Unpin": "Lösen", "Unpin from Sidebar": "Aus der Seitenleiste lösen", + "Unread": "", "Unshare All": "Alle Freigaben aufheben", "Unshare All Shared Chats": "Freigabe aller geteilten Chats aufheben", "Unshare Chat": "Chat-Freigabe entfernen", @@ -2723,6 +2761,7 @@ "Untagged": "Ohne Tag", "Untitled": "Unbenannt", "Update": "Aktualisieren", + "Update All Models": "", "Update and Copy Link": "Aktualisieren und Link kopieren", "Update Email": "E-Mail aktualisieren", "Update embedding model": "Embedding-Modell aktualisieren", @@ -2780,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "Übernimmt beim PDF-Export von Chats die Formatierung.", "Use the active chat title as the browser tab title.": "Verwendet den Titel des aktiven Chats als Titel des Browser-Tabs.", "Use the rich composer instead of a plain textarea.": "Verwendet das Rich-Text-Eingabefeld statt eines einfachen Textfelds.", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "Verwendet TLS für die Verbindung zum LDAP-Server.", "Use Web Search?": "Websuche verwenden?", "user": "Benutzer", @@ -2794,6 +2834,7 @@ "User Preview": "Benutzervorschau", "User ratings (thumbs up/down)": "Benutzerbewertungen (Daumen hoch/runter)", "User Status": "Nutzerstatus", + "User Variables": "", "User Webhooks": "Benutzer-Webhooks", "Username": "Benutzername", "Username Claim": "Benutzername-Claim", @@ -2808,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "Gültige Zeiteinheiten: 's', 'm', 'h', 'd', 'w' oder '-1' für keinen Ablauf.", "Validate Certificate": "Zertifikat prüfen", "Validate SSL certificates when fetching web content.": "Prüft SSL-Zertifikate beim Abrufen von Webinhalten.", + "Value": "", "Valves": "Valves", "Valves updated": "Valves aktualisiert", "Valves updated successfully": "Valves erfolgreich aktualisiert", "variable": "Variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "Vektorfeld", "Verify Connection": "Verbindung prüfen", "Verify SSL Certificate": "SSL-Zertifikat prüfen", diff --git a/src/lib/i18n/locales/dg-DG/translation.json b/src/lib/i18n/locales/dg-DG/translation.json index a89dba254f..a3a63788df 100644 --- a/src/lib/i18n/locales/dg-DG/translation.json +++ b/src/lib/i18n/locales/dg-DG/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Base URL", "API Key": "API Key", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Check Again", "Check for updates": "Check for updates", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Choose model before saving... Wow choose first.", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "Confirm Password", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Default User Role", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Edit Wowser", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Enabled wow", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Failed to save conversation borks", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLMs can make borks. Verify important info.", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' has been successfully downloaded.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' is already in queue for downloading.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "", "Model {{name}} is now {{status}}": "", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "", "Previous 7 days": "", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "RESULT much", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Search very search", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "", "Send a Message": "Send a Message much message", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Stop Sequence much stop", @@ -2516,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "user much user", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "variable very variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/el-GR/translation.json b/src/lib/i18n/locales/el-GR/translation.json index de26584cab..83c4a217f9 100644 --- a/src/lib/i18n/locales/el-GR/translation.json +++ b/src/lib/i18n/locales/el-GR/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Προσθήκη Χρήστη", "Add User Group": "Προσθήκη Ομάδας Χρηστών", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Επιτρέπεται η Τοποθεσία Χρήστη", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "και δημιουργήστε έναν νέο κοινόχρηστο σύνδεσμο.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Βασικό URL API", "API Key": "Κλειδί API", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Προσθήκη Knowledge", "Attach Notes": "Προσθήκη Σημειώσεων", "Attach Webpage": "Προσθήκη ιστότοπου", @@ -430,8 +434,11 @@ "Chat Permissions": "Δικαιώματα Συνομιλίας", "Chat Tags Auto-Generation": "Αυτόματη Γενιά Ετικετών Συνομιλίας", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Συνομιλίες", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Ελέγξτε ξανά", "Check for updates": "Έλεγχος για ενημερώσεις", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Επιλέξτε ένα μοντέλο πριν αποθηκεύσετε...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Καθαρισμός μνήμης", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "Επιβεβαίωση", "Confirm Password": "Επιβεβαίωση Κωδικού", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Επιβεβαιώστε την ενέργειά σας", "Confirm your new password": "Επιβεβαιώστε τον νέο σας κωδικό", "Confirm Your Password": "Επιβεβαιώστε τον Κωδικό σας", @@ -719,6 +729,7 @@ "Default to ALL": "Προεπιλογή σε ΟΛΑ", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Η προεπιλογή είναι η τμηματοποιημένη ανάκτηση για στοχευμένη και σχετική εξαγωγή περιεχομένου, κάτι που συνιστάται στις περισσότερες περιπτώσεις.", + "Default Upload Mode": "", "Default User Role": "Προεπιλεγμένος Ρόλος Χρήστη", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Υπαγόρευση", "Didn't fully follow instructions": "Δεν ακολούθησε πλήρως τις οδηγίες", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "Η λήψη ακυρώθηκε", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Επεξεργασία Χρήστη", "Edit User Group": "Επεξεργασία Ομάδας Χρηστών", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Ενεργοποιημένο", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "Αποτυχία απεικόνισης διαγράμματος", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Αποτυχία αποθήκευσης συνδέσεων", "Failed to save conversation": "Αποτυχία αποθήκευσης συνομιλίας", "Failed to save models configuration": "Αποτυχία αποθήκευσης ρυθμίσεων μοντέλων", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "Φάκελοι", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Συνέχιση", "Follow Up Generation": "Δημιουργία Συνέχισης", "Follow Up Generation Prompt": "Προτροπή Δημιουργίας Συνέχισης", @@ -1289,6 +1306,7 @@ "Generate an image": "Δημιουργία εικόνας", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Κρατήστε στην πλευρική μπάρα", "Key": "Κλειδί", "Key is required": "Το κλειδί είναι απαραίτητο", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "Πρόσβαση στο Knowledge", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Ακούγεται...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "Τα LLM μπορούν να κάνουν λάθη. Επαληθεύστε σημαντικές πληροφορίες.", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Μάρτιος", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Μοντέλο", "Model '{{modelName}}' has been successfully downloaded.": "Το μοντέλο '{{modelName}}' κατεβάστηκε με επιτυχία.", "Model '{{modelTag}}' is already in queue for downloading.": "Το μοντέλο '{{modelTag}}' βρίσκεται ήδη στην ουρά για λήψη.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Το μοντέλο {{modelName}} δεν έχει δυνατότητα όρασης", "Model {{name}} is now {{status}}": "Το μοντέλο {{name}} είναι τώρα {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "Επόμενο μήνυμα", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "Δεν βρέθηκαν λειτουργίες", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Δεν βρέθηκαν εργαλεία", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Δεν βρέθηκαν χρήστες.", "No valves": "", "No valves to update": "Δεν υπάρχουν βαλβίδες για ενημέρωση", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ωχ! Υπάρχουν αρχεία που εξακολουθούν να ανεβαίνουν. Παρακαλώ περιμένετε να ολοκληρωθεί η μεταφόρτωση.", "Oops! There was an error in the previous response.": "Ωχ! Υπήρξε σφάλμα στην προηγούμενη απάντηση.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ωχ! Χρησιμοποιείτε μια μη υποστηριζόμενη μέθοδο (μόνο frontend). Παρακαλώ σερβίρετε το WebUI από το backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Άρνηση δικαιώματος κατά την πρόσβαση σε μέσα συσκευές", "Permission denied when accessing microphone": "Άρνηση δικαιώματος κατά την πρόσβαση σε μικρόφωνο", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID Προθέματος", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Το ID Προθέματος χρησιμοποιείται για να αποφεύγονται συγκρούσεις με άλλες συνδέσεις προσθέτοντας ένα πρόθεμα στα IDs των μοντέλων - αφήστε κενό για απενεργοποίηση", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Προεπισκόπηση", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Προηγούμενες 30 ημέρες", "Previous 7 days": "Προηγούμενες 7 ημέρες", "Previous message": "Προηγούμενο μήνυμα", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Ιδιωτικό", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Επαναφορά Αποθήκευσης Διανυσμάτων/Knowledge", "Reset view": "Επαναφορά προβολής", "Response": "Απάντηση", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Οι ειδοποιήσεις απάντησης δεν μπορούν να ενεργοποιηθούν καθώς οι άδειες του ιστότοπου έχουν αρνηθεί. Παρακαλώ επισκεφτείτε τις ρυθμίσεις του περιηγητή σας για να δώσετε την απαραίτητη πρόσβαση.", "Response Splitting": "", "Response Watermark": "Υδρογράφημα Απάντησης", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Αποτέλεσμα", "RESULT": "Αποτέλεσμα", + "Retained Messages": "", "Retrieval": "Ανάκτηση", "Retrieval Query Generation": "Δημιουργία Ερωτήματος Ανάκτησης", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Αναζήτηση", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Φίλτρα Αναζήτησης", + "Search folders": "", "search for archived chats": "αναζήτηση για αρχειοθετημένες συνομιλίες", "search for folders": "αναζήτηση για φακέλους", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Τα επιλεγμένα μοντέλα δεν υποστηρίζουν είσοδο εικόνων", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Αποστολή", "Send a Message": "Αποστολή Μηνύματος", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Σταμάτημα", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Σειρά Παύσης", @@ -2516,6 +2554,7 @@ "Support": "Υποστήριξη", "Support this plugin:": "Υποστήριξη αυτού του plugin:", "Supported MIME Types": "Υποστηριζόμενοι τύποι MIME", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Ξεκαρφίτσωμα", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Χωρίς Ετικέτες", "Untitled": "", "Update": "Ενημέρωση", + "Update All Models": "", "Update and Copy Link": "Ενημέρωση και Αντιγραφή Συνδέσμου", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "χρήστης", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Webhooks Χρήστη", "Username": "Όνομα Χρήστη", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Βαλβίδες", "Valves updated": "Οι βαλβίδες ενημερώθηκαν", "Valves updated successfully": "Οι βαλβίδες ενημερώθηκαν με επιτυχία", "variable": "μεταβλητή", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Επαλήθευση Σύνδεσης", "Verify SSL Certificate": "Επαλήθευση Πιστοποιητικού SSL", diff --git a/src/lib/i18n/locales/en-GB/translation.json b/src/lib/i18n/locales/en-GB/translation.json index d1b8c5b178..3807e86746 100644 --- a/src/lib/i18n/locales/en-GB/translation.json +++ b/src/lib/i18n/locales/en-GB/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "", "API Key": "", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "", "Check for updates": "", @@ -439,6 +446,7 @@ "Choose a model before saving...": "", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "Download cancelled", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Enable, disable, or customise the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.", "Enabled": "", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "Failed to render visualisation", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1257,7 +1274,6 @@ "Format Markdown in previews and compact content surfaces.": "", "Format Markdown syntax in assistant responses.": "", "Format Markdown syntax in your own messages.": "", - "Follow assistant responses as they are generated.": "", "Formatting may be inconsistent from source.": "", "Forward": "", "Forwards system user OAuth access token to authenticate": "", @@ -1290,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1468,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1541,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "", "Loaded": "", "Loader": "", @@ -1582,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1654,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "", "Model '{{modelTag}}' is already in queue for downloading.": "", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "", "Model {{name}} is now {{status}}": "", @@ -1753,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1785,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1826,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1897,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1974,8 +1999,8 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", - "Permanently delete every chat after confirmation.": "", "Percentage of recent messages to keep after older messages are summarized.": "Percentage of recent messages to keep after older messages are summarised.", + "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", "Permission denied when accessing microphone: {{error}}": "", @@ -2038,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2045,7 +2071,10 @@ "Previous 30 days": "", "Previous 7 days": "", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2156,7 +2185,6 @@ "Render Markdown in User Messages": "", "Render messages in compact bubble containers.": "", "Repeat": "", - "Retained Messages": "", "Reply": "", "Reply in Thread": "", "Reply to thread...": "", @@ -2189,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2233,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "", @@ -2249,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2334,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "", "Send a Message": "", @@ -2454,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2489,6 +2522,7 @@ "STDOUT/STDERR": "", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "", @@ -2520,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2718,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2725,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "", "Update Email": "", "Update embedding model": "", @@ -2782,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "", @@ -2796,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2810,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index c14841a9a7..0bce90886d 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "", "API Key": "", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "", "Check for updates": "", @@ -439,6 +446,7 @@ "Choose a model before saving...": "", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -571,7 +581,7 @@ "Connect to a stable-diffusion-webui server running with the `--api` flag.": "", "Connect to an AI provider to start chatting": "", "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "", - "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "", + "Connect to Open Terminal instances. Admins and users granted access can use file browsing and terminal tools through these servers.": "", "Connect to the ComfyUI server used for generation.": "", "Connect to the ComfyUI server used for image edits.": "", "Connect to your own OpenAI compatible API endpoints.": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1257,7 +1274,6 @@ "Format Markdown in previews and compact content surfaces.": "", "Format Markdown syntax in assistant responses.": "", "Format Markdown syntax in your own messages.": "", - "Follow assistant responses as they are generated.": "", "Formatting may be inconsistent from source.": "", "Forward": "", "Forwards system user OAuth access token to authenticate": "", @@ -1290,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1468,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1541,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "", "Loaded": "", "Loader": "", @@ -1582,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1654,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "", "Model '{{modelTag}}' is already in queue for downloading.": "", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "", "Model {{name}} is now {{status}}": "", @@ -1753,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "Next message", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1785,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1826,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1897,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1974,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2037,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2044,7 +2071,10 @@ "Previous 30 days": "", "Previous 7 days": "", "Previous message": "Previous message", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2187,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2231,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "", @@ -2247,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2332,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "", "Send a Message": "", @@ -2452,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2487,6 +2522,7 @@ "STDOUT/STDERR": "", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "", @@ -2518,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2716,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2723,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "", "Update Email": "", "Update embedding model": "", @@ -2780,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "", @@ -2794,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2808,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/es-ES/translation.json b/src/lib/i18n/locales/es-ES/translation.json index c62cfb98a0..91244442d3 100644 --- a/src/lib/i18n/locales/es-ES/translation.json +++ b/src/lib/i18n/locales/es-ES/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "Añade a favoritos", "Add User": "Añadir Usuario", "Add User Group": "Añadir grupo de usuarios", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Añadir página Web", "Add your Open Terminal URL and API key in Settings → Integrations.": "Añadir la URL y la clave API de OpenTerminal en Configuración → Integraciones", @@ -197,6 +198,7 @@ "Allow User Location": "Permitir Ubicación del Usuario", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "y crear un nuevo enlace compartido.", "Android": "Android", "Anyone": "Cualquiera", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Base API", "API Key": "Clave API", @@ -295,6 +298,7 @@ "At time of event": "En el momento del evento", "Attach File From Knowledge": "Adjuntar Archivo desde Conocimiento", "Attach Files": "Adjuntar Archivos", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Adjuntar Conocimiento", "Attach Notes": "Adjuntar Notas", "Attach Webpage": "Adjuntar Página Web", @@ -437,8 +441,11 @@ "Chat Permissions": "Permisos del Chat", "Chat Tags Auto-Generation": "AutoGeneración de Etiquetas de Chat", "Chat unshared successfully.": "Chat descompartido correctamente", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "chats", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "Compartir Chats Publicamente", "Check Again": "Verifica de nuevo", "Check for updates": "Buscar actualizaciones", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Escoge un modelo antes de guardar...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Liberar memoria", "Clear Memory": "Liberar Memoria", @@ -571,6 +580,7 @@ "Confirm": "Confirmar", "Confirm Password": "Confirma Contraseña", "Confirm Prompt from Embed": "Confirma Indicador desde la Incrustación", + "Confirm recording": "", "Confirm your action": "Confirma tu acción", "Confirm your new password": "Confirma tu nueva contraseña", "Confirm Your Password": "Confirma Tu Contraseña", @@ -727,6 +737,7 @@ "Default to ALL": "Predeterminado a TODOS", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Por defecto está predeterminada una segmentación de la recuperación para una extracción de contenido centrado y relevante, recomendado para la mayoría de los casos.", + "Default Upload Mode": "", "Default User Role": "Rol predeterminado de los nuevos usuarios", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "Deseleccionar", "Detect Artifacts Automatically": "Detectar Artefactos Automáticamente", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dictar", "Didn't fully follow instructions": "No seguiste completamente las instrucciones", "Direct": "Directo", @@ -846,6 +858,7 @@ "Download as SVG": "Descargar como SVG", "Download canceled": "Descarga cancelada", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "Editar Conexión del Terminal", "Edit User": "Editar Usuario", "Edit User Group": "Editar Grupo de Usuarios", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Editar el contenido de workflow.json", "edited": "editado", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Habilite, deshabilite o personalice las etiquetas de razonamiento utilizadas por el modelo. \"HAbilitado\" usa etiquetas predeterminadas, \"Deshabilitado\" desactiva las etiquetas de razonamiento y \"Personalizado\" le permite especificar sus propias etiquetas de inicio y fin.", "Enabled": "Habilitado", + "End call": "", "End Tag": "Etiqueta de Fin", "Endpoint": "", "Endpoint URL": "Endpoint URL", @@ -1185,6 +1200,7 @@ "Failed to remove member": "Fallo al eliminar miembro", "Failed to render diagram": "Fallo al renderizar el diagrama", "Failed to render visualization": "Fallo al renderizar la visualización", + "Failed to save chat variables": "", "Failed to save connections": "Fallo al guardar las conexiones", "Failed to save conversation": "Fallo al guardar la conversación", "Failed to save models configuration": "Fallo al guardar la configuración de los modelos", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "Carpeta actualizada correctamente", "Folders": "Carpetas", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Seguimiento", "Follow Up Generation": "Seguimiento de la Generación", "Follow Up Generation Prompt": "Seguimiento de la Generación del Indicador", @@ -1299,6 +1316,7 @@ "Generate an image": "Generar una imagen", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Generar y editar imágenes", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Generar Par de Mensajes", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Mantener en Barra Lateral", "Key": "Clave", "Key is required": "La Clave es requerida", + "key_name": "", "Keyboard": "", "Knowledge": "Conocimiento", "Knowledge Access": "Permiso a Conocimiento", @@ -1550,9 +1569,9 @@ "List": "Lista", "List calendars, search, create, update, and delete calendar events": "Listar, buscar, crear, actualizar y borrar eventos en calendarios", "Listening...": "Escuchando...", + "LiteLLM": "", "Live": "En Directo", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Los LLMs pueden cometer errores. Verifica la información importante.", "Loaded": "Cargado", "Loader": "Cargador", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marzo", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Divisor de Texto Encabezado de Markdown", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Modelo", "Model '{{modelName}}' has been successfully downloaded.": "Modelo '{{modelName}}' se ha descargado correctamente.", "Model '{{modelTag}}' is already in queue for downloading.": "Modelo '{{modelTag}}' ya está en cola para descargar.", - "Model {{modelId}} not found": "Modelo {{modelId}} no encontrado", "Model {{modelName}} deleted successfully": "Modelo {{modelName}} borrado correctamente", "Model {{modelName}} is not vision capable": "Modelo {{modelName}} no esta capacitado para visión", "Model {{name}} is now {{status}}": "Modelo {{name}} está ahora {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "Nuevo Webhook", "new-channel": "nuevo-canal", "Next message": "Siguiente mensaje", + "Next month": "", "Next page": "", "Next run": "Siguiente ejecución", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Sin acceso concedido. Privado para tí.", "No actions found": "", "No activity data": "Sin datos de actividad", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "Ningún archivo en esta base de conocimiento.", "No files yet. Upload files or run Python code to create them.": "Todavía no hay ficheros. Sube archivos o ejecuta código Python para crearlos.", "No filters found": "", + "No folders": "", "No functions found": "No se encontraron funciones", "No groups found": "No se encontraron grupos", "No history available": "No hay historial disponible", @@ -1835,6 +1859,7 @@ "No tools accessible": "Ninguna herramienta accesible", "No tools found": "No se encontraron herramientas", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "No se encontraron usuarios.", "No valves": "No hay válvulas", "No valves to update": "No hay válvulas para actualizar", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "¡vaya! Todavía hay archivos subiendose. Por favor, espera a que se complete la subida.", "Oops! There was an error in the previous response.": "¡vaya! Hubo un error en la respuesta previa.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "¡vaya! Estás usando un método no soportado (solo interfaz frontal-frontend). Por favor sirve WebUI desde el interfaz trasero (servidor backend).", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Contenido de la SobreCapa Usuario Pendiente", "Pending User Overlay Title": "Título de la SobreCapa Usuario Pendiente", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Permiso denegado accediendo a los dispositivos", "Permission denied when accessing microphone": "Permiso denegado accediendo al micrófono", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "prefijo ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "El prefijo ID se utiliza para evitar conflictos con otras conexiones al añadir un prefijo a los IDs de modelo, dejar vacío para deshabilitarlo", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Prevenir la Creación de Archivos", "Preview": "Previsualización", @@ -2053,7 +2081,10 @@ "Previous 30 days": "30 días previos", "Previous 7 days": "7 días previos", "Previous message": "Mensaje anterior", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privado", "Private conversation between selected users": "Conversación privada entre l@s usuari@s seleccionados", "Production version updated": "Versión de Producción actualizada", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Reiniciar Almacenamiento de Vectores/Conocimiento", "Reset view": "Reiniciar Vista", "Response": "Respuesta", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Las notificaciones de respuesta no pueden activarse ya que los permisos del sitio web han sido denegados. Por favor, comprueba la configuración de tu navegador para otorgar el permiso necesario.", "Response Splitting": "", "Response Watermark": "Marca de Agua en Respuesta", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultado", "RESULT": "Resultado", + "Retained Messages": "", "Retrieval": "Recuperación", "Retrieval Query Generation": "Consulta de Generación de Recuperación", "Retrieved {{count}} sources": "Recuperadas {{count}} fuentes", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "El tiempo de programado debe ser futuro", "Scopes": "", "Scroll On Branch Change": "Desplazamiento al Cambiar Rama", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Desplazar al principio", "Search": "Buscar", @@ -2258,6 +2292,7 @@ "Search Files": "Buscar archivos", "Search filters": "", "Search Filters": "Buscar Filtros", + "Search folders": "", "search for archived chats": "buscar chats archivados", "search for folders": "buscar carpetas", "search for pinned chats": "buscar chats fijados", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "Modelo seleccinado: {{modelName}}", "Selected model(s) do not support image inputs": "Modelo(s) seleccionado(s) no admiten entradas de imagen", + "Selected models define incompatible Chat Variables.": "", "semantic": "semántica", "Send": "Enviar", "Send a Message": "Enviar un Mensaje", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "Compartir Habilidad Publicamente", "Skills Sharing": "Compartir Habilidad", "Skip Cache": "Evitar Caché", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Algo ha ido mal :/", "Sonar": "Sonar", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Pasos", "Stop": "Detener", + "Stop camera": "", "Stop Download": "Detener la Descarga", "Stop Generating": "Parar la Generación", "Stop Sequence": "Secuencia de Parada", @@ -2530,6 +2568,7 @@ "Support": "Soportar", "Support this plugin:": "Apoya este plugin:", "Supported MIME Types": "Tipos MIME Soportados", + "Switch camera": "", "Switch to JSON editor": "Cambiar a editor JSON", "Switch to visual editor": "Cambiar a editor visual", "Sync": "Sincronizar", @@ -2728,6 +2767,7 @@ "Unmute": "Desilenciar", "Unpin": "Desfijar", "Unpin from Sidebar": "Desfijar de la Barra LAteral", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Descompartir Chat", @@ -2735,6 +2775,7 @@ "Untagged": "Sin Etiqueta", "Untitled": "Sin Título", "Update": "Actualizar", + "Update All Models": "", "Update and Copy Link": "Actualizar y Copiar Enlace", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "usuario", @@ -2806,6 +2848,7 @@ "User Preview": "Previsualizar Usuario", "User ratings (thumbs up/down)": "Calificaciones de los usuarios (pulgares arriba/abajo)", "User Status": "Estado del Usuario", + "User Variables": "", "User Webhooks": "Usuario Webhooks", "Username": "Nombre de Usuario", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Válvulas", "Valves updated": "Válvulas actualizadas", "Valves updated successfully": "Válvulas actualizados correctamente", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Verificar Conexión", "Verify SSL Certificate": "Verificar Certificado SSL", diff --git a/src/lib/i18n/locales/et-EE/translation.json b/src/lib/i18n/locales/et-EE/translation.json index 1d9854149c..5997c126b6 100644 --- a/src/lib/i18n/locales/et-EE/translation.json +++ b/src/lib/i18n/locales/et-EE/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Lisa lemmikutesse", "Add User": "Lisa kasutaja", "Add User Group": "Lisa kasutajagrupp", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Lisa veebileht", "Add your Open Terminal URL and API key in Settings → Integrations.": "Lisage oma Open Terminali URL ja API võti menüüs Seaded → Integratsioonid.", @@ -190,6 +191,7 @@ "Allow User Location": "Luba kasutaja asukoht", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "ja looge uus jagatud link.", "Android": "Android", "Anyone": "Igaüks", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API baas-URL", "API Key": "API võti", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "Lisa fail teadmistest", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Lisa teadmised", "Attach Notes": "Lisa märkmed", "Attach Webpage": "Lisa veebileht", @@ -430,8 +434,11 @@ "Chat Permissions": "Vestluse õigused", "Chat Tags Auto-Generation": "Vestluse siltide automaatne genereerimine", "Chat unshared successfully.": "Vestluse jagamine edukalt lõpetatud.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "vestlused", "Chats": "Vestlused", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Kontrolli uuesti", "Check for updates": "Kontrolli uuendusi", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Valige mudel enne salvestamist...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Tühjenda mälu", "Clear Memory": "Tühjenda mälu", @@ -563,6 +572,7 @@ "Confirm": "Kinnita", "Confirm Password": "Kinnita parool", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Kinnita oma toiming", "Confirm your new password": "Kinnita oma uus parool", "Confirm Your Password": "Kinnita oma parool", @@ -719,6 +729,7 @@ "Default to ALL": "Vaikimisi KÕIK", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Vaikimisi kasutada segmenteeritud päringut keskendunud ja asjakohase sisu eraldamiseks; soovitatav enamikel juhtudel.", + "Default Upload Mode": "", "Default User Role": "Vaikimisi kasutaja roll", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Tuvasta artefaktid automaatselt", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dikteeri", "Didn't fully follow instructions": "Ei järginud täielikult juhiseid", "Direct": "Otsene", @@ -838,6 +850,7 @@ "Download as SVG": "Laadi alla SVG-na", "Download canceled": "Allalaadimine tühistatud", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Muuda terminaliühendust", "Edit User": "Muuda kasutajat", "Edit User Group": "Muuda kasutajagruppi", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Muuda workflow.json sisu", "edited": "muudetud", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Luba, keela või kohanda mudeli kasutatavaid arutlussilte. \"Lubatud\" kasutab vaikimisi silte, \"Keelatud\" lülitab arutlussildid välja ja \"Kohandatud\" võimaldab määrata oma algus- ja lõpusildid.", "Enabled": "Lubatud", + "End call": "", "End Tag": "Lõpusilt", "Endpoint": "", "Endpoint URL": "Lõpp-punkt URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Liikme eemaldamine ebaõnnestus", "Failed to render diagram": "Diagrammi renderdamine ebaõnnestus", "Failed to render visualization": "Visualiseerimise renderdamine ebaõnnestus", + "Failed to save chat variables": "", "Failed to save connections": "Ühenduste salvestamine ebaõnnestus", "Failed to save conversation": "Vestluse salvestamine ebaõnnestus", "Failed to save models configuration": "Mudelite konfiguratsiooni salvestamine ebaõnnestus", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Kaust edukalt uuendatud", "Folders": "Kaustad", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Järelküsimus", "Follow Up Generation": "Järelküsimuste genereerimine", "Follow Up Generation Prompt": "Järelküsimuse genereerimise sisend", @@ -1289,6 +1306,7 @@ "Generate an image": "Genereeri pilt", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Genereeri ja muuda pilte", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Genereeri sõnumipaar", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Hoia külgribal", "Key": "Võti", "Key is required": "Võti on nõutav", + "key_name": "", "Keyboard": "", "Knowledge": "Teadmised", "Knowledge Access": "Teadmiste juurdepääs", @@ -1540,9 +1559,9 @@ "List": "Nimekiri", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Kuulamine...", + "LiteLLM": "", "Live": "Reaalajas", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM-id võivad teha vigu. Kontrollige olulist teavet.", "Loaded": "", "Loader": "Laadija", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Märts", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown päise teksti tükeldaja", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Mudel", "Model '{{modelName}}' has been successfully downloaded.": "Mudel '{{modelName}}' on edukalt alla laaditud.", "Model '{{modelTag}}' is already in queue for downloading.": "Mudel '{{modelTag}}' on juba allalaadimise järjekorras.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Mudel {{modelName}} ei ole võimeline visuaalseid sisendeid töötlema", "Model {{name}} is now {{status}}": "Mudel {{name}} on nüüd {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "Uus webhook", "new-channel": "uus-kanal", "Next message": "Järgmine sõnum", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Pole juurdepääsuõigusi. Privaatne teile.", "No actions found": "", "No activity data": "Tegevusandmed puuduvad", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "Selles teadmiste baasis pole faile.", "No files yet. Upload files or run Python code to create them.": "Faile pole veel. Laadige failid üles või käivitage Pythoni kood nende loomiseks.", "No filters found": "", + "No folders": "", "No functions found": "Funktsioone ei leitud", "No groups found": "Gruppe ei leitud", "No history available": "Ajalugu pole saadaval", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Tööriistu ei leitud", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Kasutajaid ei leitud.", "No valves": "Klappe pole", "No valves to update": "Pole klappe, mida uuendada", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Oih! Failide üleslaadimine on veel pooleli. Palun oodake, kuni üleslaadimine lõpeb.", "Oops! There was an error in the previous response.": "Oih! Eelmises vastuses oli viga.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oih! Kasutate toetamatut meetodit (ainult kasutajaliides). Palun serveerige WebUI tagarakendusest.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Ootava kasutaja kattekihi sisu", "Pending User Overlay Title": "Ootava kasutaja kattekihi pealkiri", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Juurdepääs meediumiseadmetele keelatud", "Permission denied when accessing microphone": "Juurdepääs mikrofonile keelatud", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefiksi ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefiksi ID-d kasutatakse teiste ühendustega konfliktide vältimiseks, lisades mudeli ID-dele prefiksi - jätke tühjaks keelamiseks", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Keela failide loomine", "Preview": "Eelvaade", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Eelmised 30 päeva", "Previous 7 days": "Eelmised 7 päeva", "Previous message": "Eelmine sõnum", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privaatne", "Private conversation between selected users": "Privaatne vestlus valitud kasutajate vahel", "Production version updated": "Tootmise versioon uuendatud", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Lähtesta vektormälu/teadmised", "Reset view": "Lähtesta vaade", "Response": "Vastus", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Vastuste teavitusi ei saa aktiveerida, kuna veebisaidi õigused on keelatud. Vajalike juurdepääsude andmiseks külastage oma brauseri seadeid.", "Response Splitting": "", "Response Watermark": "Vastuse vesimärk", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Tulemus", "RESULT": "TULEMUS", + "Retained Messages": "", "Retrieval": "Pärimine", "Retrieval Query Generation": "Pärimise päringu genereerimine", "Retrieved {{count}} sources": "Hangitud {{count}} allikat", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Keri haru muutmisel", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Otsing", @@ -2245,6 +2279,7 @@ "Search Files": "Otsi faile", "Search filters": "", "Search Filters": "Otsingu filtrid", + "Search folders": "", "search for archived chats": "otsi arhiveeritud vestlusi", "search for folders": "otsi kaustu", "search for pinned chats": "otsi kinnitatud vestlusi", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "Valitud mudel: {{modelName}}", "Selected model(s) do not support image inputs": "Valitud mudel(id) ei toeta pilte sisendina", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantiline", "Send": "Saada", "Send a Message": "Saada sõnum", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "Oskuste avalik jagamine", "Skills Sharing": "Oskuste jagamine", "Skip Cache": "Jäta vahemälu vahele", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Midagi läks valesti :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Sammud", "Stop": "Peata", + "Stop camera": "", "Stop Download": "Peata allalaadimine", "Stop Generating": "Peata genereerimine", "Stop Sequence": "Lõpetamise järjestus", @@ -2516,6 +2554,7 @@ "Support": "Tugi", "Support this plugin:": "Toeta seda pistikprogrammi:", "Supported MIME Types": "Toetatud MIME tüübid", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "Sünkrooni", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Eemalda kinnitus", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Lõpeta vestluse jagamine", @@ -2721,6 +2761,7 @@ "Untagged": "Sildistamata", "Untitled": "Pealkirjata", "Update": "Uuenda", + "Update All Models": "", "Update and Copy Link": "Uuenda ja kopeeri link", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "kasutaja", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Kasutajate hinnangud (pöidlad üles/alla)", "User Status": "Kasutaja olek", + "User Variables": "", "User Webhooks": "Kasutaja webhook'id", "Username": "Kasutajanimi", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Klapid", "Valves updated": "Klapid uuendatud", "Valves updated successfully": "Klapid edukalt uuendatud", "variable": "muutuja", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Kontrolli ühendust", "Verify SSL Certificate": "Kontrolli SSL-sertifikaati", diff --git a/src/lib/i18n/locales/eu-ES/translation.json b/src/lib/i18n/locales/eu-ES/translation.json index 7e0c707f25..1f32cd0599 100644 --- a/src/lib/i18n/locales/eu-ES/translation.json +++ b/src/lib/i18n/locales/eu-ES/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Gehitu Erabiltzailea", "Add User Group": "Gehitu Erabiltzaile Taldea", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Baimendu Erabiltzailearen Kokapena", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "eta sortu partekatutako esteka berri bat.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Oinarri URLa", "API Key": "API Gakoa", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Txat Baimenak", "Chat Tags Auto-Generation": "Txat Etiketen Auto-Sorkuntza", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Txatak", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Egiaztatu Berriro", "Check for updates": "Bilatu eguneraketak", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Aukeratu eredu bat gorde aurretik...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Garbitu memoria", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "Berretsi", "Confirm Password": "Berretsi Pasahitza", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Berretsi zure ekintza", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "Lehenetsi GUZTIAK", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Erabiltzaile Rol Lehenetsia", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Ez ditu jarraibideak guztiz jarraitu", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "Deskarga bertan behera utzi da", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Editatu Erabiltzailea", "Edit User Group": "Editatu Erabiltzaile Taldea", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Gaituta", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Huts egin du elkarrizketa gordetzean", "Failed to save models configuration": "Huts egin du ereduen konfigurazioa gordetzean", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Gakoa", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Ezagutza", "Knowledge Access": "Ezagutzarako Sarbidea", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Entzuten...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLMek akatsak egin ditzakete. Egiaztatu informazio garrantzitsua.", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Martxoa", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Modeloa", "Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' modeloa ongi deskargatu da.", "Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' modeloa dagoeneko deskarga ilaran dago.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "{{modelName}} modeloak ez du ikusmen gaitasunik", "Model {{name}} is now {{status}}": "{{name}} modeloa orain {{status}} dago", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Ez da erabiltzailerik aurkitu.", "No valves": "", "No valves to update": "Ez dago balbularik eguneratzeko", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ui! Oraindik fitxategiak kargatzen ari dira. Mesedez, itxaron karga amaitu arte.", "Oops! There was an error in the previous response.": "Ui! Errore bat egon da aurreko erantzunean.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ui! Onartzen ez den metodo bat erabiltzen ari zara (frontend soilik). Mesedez, zerbitzatu WebUI-a backendetik.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Baimena ukatu da multimedia gailuak atzitzean", "Permission denied when accessing microphone": "Baimena ukatu da mikrofonoa atzitzean", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Aurrizki ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Aurrizki IDa erabiltzen da beste konexioekin gatazkak saihesteko modelo IDei aurrizki bat gehituz - utzi hutsik desgaitzeko", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Aurreko 30 egunak", "Previous 7 days": "Aurreko 7 egunak", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Berrezarri bektore biltegia/ezagutza", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Erantzunen jakinarazpenak ezin dira aktibatu webgunearen baimenak ukatu direlako. Mesedez, bisitatu zure nabigatzailearen ezarpenak beharrezko sarbidea emateko.", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Emaitza", "RESULT": "Emaitza", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Bilatu", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Bilaketa iragazkiak", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Hautatutako modelo(e)k ez dute irudi sarrerarik onartzen", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Bidali", "Send a Message": "Bidali mezu bat", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Gelditu", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Gelditzeko sekuentzia", @@ -2516,6 +2554,7 @@ "Support": "Laguntza", "Support this plugin:": "Lagundu plugin hau:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Kendu aingura", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Etiketatu gabea", "Untitled": "", "Update": "Eguneratu", + "Update All Models": "", "Update and Copy Link": "Eguneratu eta kopiatu esteka", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "erabiltzailea", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Erabiltzaile-izena", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Balbulak", "Valves updated": "Balbulak eguneratuta", "Valves updated successfully": "Balbulak ongi eguneratu dira", "variable": "aldagaia", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/fa-IR/translation.json b/src/lib/i18n/locales/fa-IR/translation.json index 92d9caa165..71deb2d20c 100644 --- a/src/lib/i18n/locales/fa-IR/translation.json +++ b/src/lib/i18n/locales/fa-IR/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "افزودن کاربر", "Add User Group": "افزودن گروه کاربری", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "اجازهٔ موقعیت مکانی کاربر", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "و یک پیوند اشتراک\u200cگذاری جدید ایجاد کنید.", "Android": "اندروید", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "نشانی پایهٔ API", "API Key": "کلید API", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "پیوست فایل از دانش", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "پیوست دانش", "Attach Notes": "پیوست یادداشت\u200cها", "Attach Webpage": "پیوست صفحه وب", @@ -430,8 +434,11 @@ "Chat Permissions": "مجوزهای گفتگو", "Chat Tags Auto-Generation": "تولید خودکار برچسب\u200cهای گفتگو", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "گفتگو\u200cها", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "بررسی دوباره", "Check for updates": "بررسی به\u200cروزرسانی", @@ -439,6 +446,7 @@ "Choose a model before saving...": "قبل از ذخیره یک مدل را انتخاب کنید...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "پاک کردن حافظه", "Clear Memory": "پاک کردن حافظه", @@ -563,6 +572,7 @@ "Confirm": "تایید", "Confirm Password": "تایید رمز عبور", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "عملیات خود را تایید کنید", "Confirm your new password": "رمز عبور جدید خود را تایید کنید", "Confirm Your Password": "تأیید رمز عبور", @@ -719,6 +729,7 @@ "Default to ALL": "پیش\u200cفرض به همه", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "پیش\u200cفرض به بازیابی قطعه\u200cای برای استخراج محتوای متمرکز و مرتبط، این برای اکثر موارد توصیه می\u200cشود.", + "Default Upload Mode": "", "Default User Role": "نقش کاربر پیش فرض", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "تشخیص خودکار مصنوعات", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "دیکته کردن", "Didn't fully follow instructions": "نمی تواند دستورالعمل را کامل پیگیری کند", "Direct": "مستقیم", @@ -838,6 +850,7 @@ "Download as SVG": "دانلود به صورت SVG", "Download canceled": "دانلود لغو شد", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "ویرایش کاربر", "Edit User Group": "ویرایش گروه کاربری", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "ویرایش محتوای workflow.json", "edited": "ویرایش شد", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "تگ\u200cهای استدلال مورد استفاده مدل را فعال، غیرفعال یا سفارشی کنید. «فعال» از تگ\u200cهای پیش\u200cفرض استفاده می\u200cکند، «غیرفعال» تگ\u200cهای استدلال را خاموش می\u200cکند، و «سفارشی» به شما امکان می\u200cدهد تگ\u200cهای شروع و پایان خود را مشخص کنید.", "Enabled": "فعال شده", + "End call": "", "End Tag": "تگ پایان", "Endpoint": "", "Endpoint URL": "آدرس URL نقطه پایانی", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "رندر دیاگرام ناموفق بود", "Failed to render visualization": "رندر بصری\u200cسازی ناموفق بود", + "Failed to save chat variables": "", "Failed to save connections": "خطا در ذخیره\u200cسازی اتصالات", "Failed to save conversation": "خطا در ذخیره\u200cسازی گفت\u200cوگو", "Failed to save models configuration": "خطا در ذخیره\u200cسازی پیکربندی مدل\u200cها", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "پوشه با موفقیت به\u200cروز شد", "Folders": "پوشه\u200cها", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "پیگیری", "Follow Up Generation": "تولید پیگیری", "Follow Up Generation Prompt": "پرامپت تولید پیگیری", @@ -1289,6 +1306,7 @@ "Generate an image": "تولید یک تصویر", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "تولید جفت پیام", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "نگه داشتن در نوار کناری", "Key": "کلید", "Key is required": "کلید مورد نیاز است", + "key_name": "", "Keyboard": "", "Knowledge": "دانش", "Knowledge Access": "دسترسی به دانش", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "در حال گوش دادن...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "مدل\u200cهای زبانی بزرگ می\u200cتوانند اشتباه کنند. اطلاعات مهم را راستی\u200cآزمایی کنید.", "Loaded": "", "Loader": "بارگذار", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "مارچ", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "مارک\u200cداون", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "مدل", "Model '{{modelName}}' has been successfully downloaded.": "مدل '{{modelName}}' با موفقیت دانلود شد.", "Model '{{modelTag}}' is already in queue for downloading.": "مدل '{{modelTag}}' در حال حاضر در صف برای دانلود است.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "مدل {{modelName}} قادر به بینایی نیست", "Model {{name}} is now {{status}}": "مدل {{name}} در حال حاضر {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "کانال-جدید", "Next message": "پیام بعدی", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "هیچ تابعی یافت نشد", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "هیچ ابزاری یافت نشد", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "کاربری یافت نشد.", "No valves": "بدون دریچه", "No valves to update": "شیری برای به\u200cروزرسانی وجود ندارد", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "اوه! هنوز فایل\u200cهایی در حال آپلود هستند. لطفاً منتظر تکمیل آپلود بمانید.", "Oops! There was an error in the previous response.": "اوه! در پاسخ قبلی خطایی رخ داد.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "اوه! شما از یک روش پشتیبانی نشده (فقط frontend) استفاده می کنید. لطفاً WebUI را از بکند اجرا کنید.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "محتوای پوشش کاربر در انتظار", "Pending User Overlay Title": "عنوان پوشش کاربر در انتظار", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "دسترسی به دستگاه\u200cهای رسانه رد شد", "Permission denied when accessing microphone": "دسترسی به میکروفون رد شد", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "شناسه پیشوند", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "شناسه پیشوند برای جلوگیری از تداخل با سایر اتصالات با افزودن پیشوند به شناسه\u200cهای مدل استفاده می\u200cشود - برای غیرفعال کردن خالی بگذارید", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "جلوگیری از ایجاد فایل", "Preview": "پیش\u200cنمایش", @@ -2043,7 +2071,10 @@ "Previous 30 days": "30 روز قبل", "Previous 7 days": "7 روز قبل", "Previous message": "پیام قبلی", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "خصوصی", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "بازنشانی ذخیره\u200cسازی برداری/دانش", "Reset view": "بازنشانی نما", "Response": "پاسخ", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "اعلان\u200cهای پاسخ نمی\u200cتوانند فعال شوند زیرا مجوزهای وب\u200cسایت رد شده\u200cاند. لطفاً تنظیمات مرورگر خود را برای اعطای دسترسی لازم بررسی کنید.", "Response Splitting": "", "Response Watermark": "واترمارک پاسخ", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "نتیجه", "RESULT": "نتیجه", + "Retained Messages": "", "Retrieval": "بازیابی", "Retrieval Query Generation": "تولید کوئری بازیابی", "Retrieved {{count}} sources": "{{count}} منبع بازیابی شد", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "اسکرول هنگام تغییر شاخه", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "جستجو", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "فیلترهای جستجو", + "Search folders": "", "search for archived chats": "جستجو برای چت\u200cهای بایگانی شده", "search for folders": "جستجو برای پوشه\u200cها", "search for pinned chats": "جستجو برای چت\u200cهای پین شده", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "مدل) های (انتخاب شده ورودیهای تصویر را پشتیبانی نمیکند", + "Selected models define incompatible Chat Variables.": "", "semantic": "معنایی", "Send": "ارسال", "Send a Message": "ارسال یک پیام", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "رد کردن کش", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "مشکلی پیش آمد :/", "Sonar": "سونار", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "مراحل", "Stop": "توقف", + "Stop camera": "", "Stop Download": "", "Stop Generating": "توقف تولید", "Stop Sequence": "توقف توالی", @@ -2516,6 +2554,7 @@ "Support": "حمایت", "Support this plugin:": "حمایت از این افزونه", "Supported MIME Types": "انواع MIME پشتیبانی شده", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "برداشتن پین", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "بدون برچسب", "Untitled": "بدون عنوان", "Update": "به\u200cروزرسانی", + "Update All Models": "", "Update and Copy Link": "به روزرسانی و کپی لینک", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "کاربر", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "وب\u200cهوک\u200cهای کاربر", "Username": "نام کاربری", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "شیرها", "Valves updated": "شیرها به\u200cروزرسانی شدند", "Valves updated successfully": "شیرها با موفقیت به\u200cروزرسانی شدند", "variable": "متغیر", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "تأیید اتصال", "Verify SSL Certificate": "تأیید گواهی SSL", diff --git a/src/lib/i18n/locales/fi-FI/translation.json b/src/lib/i18n/locales/fi-FI/translation.json index 248de0cd76..7543ef1b66 100644 --- a/src/lib/i18n/locales/fi-FI/translation.json +++ b/src/lib/i18n/locales/fi-FI/translation.json @@ -36,19 +36,19 @@ "{{COUNT}}m_time_ago": "", "{{COUNT}}w_time_ago": "", "{{COUNT}}y_time_ago": "", - "{{label}} contains invalid JSON": "", - "{{label}} must be a JSON object": "", + "{{label}} contains invalid JSON": "{{label}} sisältää virheellistä JSONia", + "{{label}} must be a JSON object": "{{label}} täytyy olla kelvollinen JSON-objekti", "{{model}} download has been canceled": "{{model}} lataus peruttu", "{{modelName}} profile image": "{{modelName}} profiilikuva", "{{NAMES}} reacted with {{REACTION}}": "{{NAMES}} reagoi {{REACTION}}", "{{user}}'s Chats": "{{user}}:n keskustelut", "{{webUIName}} Backend Required": "{{webUIName}}-backend vaaditaan", "*Prompt node ID(s) are required for image generation": "Kuvan luomiseen vaaditaan kehote-solmun ID(t)", - "1 file": "", - "1 group": "", + "1 file": "1 tiedosto", + "1 group": "1 ryhmä", "1 hour before": "1 tunti ennen", "1 Source": "1 lähde", - "1 user": "", + "1 user": "1 käyttäjä", "10 minutes before": "10 minuuttia ennen", "15 minutes before": "15 minuuttia ennen", "1m_time_ago": "", @@ -64,9 +64,9 @@ "Access": "Pääsy", "Access Control": "Käyttöoikeuksien hallinta", "Access Grants": "Käyttöoikeudet", - "Access level": "", + "Access level": "Käyttöoikeustaso", "Access List": "Pääsylista", - "Access prohibited": "", + "Access prohibited": "Pääsy kielletty", "Access updated": "Käyttöoikeus päivitetty", "Accessible to all users": "Käytettävissä kaikille käyttäjille", "Account": "Tili", @@ -79,16 +79,16 @@ "Active": "Aktiivinen", "Active Users": "Aktiiviset käyttäjät", "Activity": "Toiminta", - "Activity insights": "", + "Activity insights": "Toiminta-analytiikka", "Add": "Lisää", "Add a model ID": "Lisää mallitunnus", - "Add a preference, fact, or instruction about you": "", + "Add a preference, fact, or instruction about you": "Lisää mieltymys, tosiasia tai ohje itsestäsi", "Add a short description about what this model does": "Lisää lyhyt kuvaus siitä, mitä tämä malli tekee", "Add a tag": "Lisää tagi", "Add a tag...": "Lisää tagi...", "Add Access": "Lisää pääsy", "Add Arena Model": "Lisää Areena-malli", - "Add banner": "", + "Add banner": "Lisää banneri", "Add Connection": "Lisää yhteys", "Add Content": "Lisää sisältöä", "Add content here": "Lisää sisältöä tähän", @@ -96,18 +96,18 @@ "Add Custom Prompt": "Lisää mukautettu kehote", "Add description": "Lisää kuvaus", "Add Details": "Lisää yksityiskohtia", - "Add durable context for future chats": "", - "Add filenames, titles, sections, and snippets to improve lexical recall.": "", + "Add durable context for future chats": "Lisää pysyvä konteksti tuleviin keskusteluihin", + "Add filenames, titles, sections, and snippets to improve lexical recall.": "Lisää tiedostonimiä, otsikoita, osioita ja katkelmia parantaaksesi leksikaalista muistia.", "Add Files": "Lisää tiedostoja", "Add Image": "Lisää kuva", - "Add Knowledge Connection": "", + "Add Knowledge Connection": "Lisää tietokantayhteys", "Add location": "Lisää sijainti", "Add Member": "Lisää jäsen", "Add Members": "Lisää jäseniä", "Add Memory": "Lisää muistiin", - "Add Notification Target": "", - "Add optional profile context visible where profiles are shown.": "", - "Add prompt suggestion": "", + "Add Notification Target": "Lisää ilmoituskohde", + "Add optional profile context visible where profiles are shown.": "Lisää valinnainen profiilikonteksti, joka näkyy siellä, missä profiilit näytetään.", + "Add prompt suggestion": "Lisää kehotusehdotus", "Add Reaction": "Lisää reaktio", "Add tag": "Lisää tagi", "Add Tag": "Lisää tagi", @@ -117,99 +117,101 @@ "Add to favorites": "Lisää suosikkeihin", "Add User": "Lisää käyttäjä", "Add User Group": "Lisää käyttäjäryhmä", - "Add webhook": "", + "Add User Variable": "", + "Add webhook": "Lisää webhook", "Add webpage": "Lisää verkkosivu", "Add your Open Terminal URL and API key in Settings → Integrations.": "Lisää Open Terminal verkko-osoite ja API-avain Asetukset → Integraatiot", "Additional Config": "Lisäasetukset", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "Lisäasetukset merkille. Tämä tulisi olla JSON-merkkijono, jossa on avain-arvo-pareja. Esimerkiksi '{\"key\": \"value\"}'. Tuetut avaimet sisältävät: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level.", - "Additional Docling parameters in JSON format.": "", + "Additional Docling parameters in JSON format.": "Doclingin lisäparametrit JSON muodossa", "Additional feedback comments": "Lisäpalautteen kommentit", - "Additional JSON headers sent to the external document loader.": "", + "Additional JSON headers sent to the external document loader.": "Lisä-JSON-otsikot lähetetään ulkoiselle Document Loader:lle.", "Additional Parameters": "Lisäparametrit", - "Adjust how quickly spoken responses are played.": "", + "Adjust how quickly spoken responses are played.": "Säädä kuinka nopeasti puhutut vastaukset toistetaan", "admin": "hallinta", "Admin": "Ylläpito", "Admin Contact Email": "Ylläpidon sähköposti", - "Admin Details": "", + "Admin Details": "Ylläpidon tiedot", "Admin Panel": "Ylläpitopaneeli", - "Admin Roles": "", - "Admin-managed service account": "", + "Admin Roles": "Ylläpidon roolit", + "Admin-managed service account": "Ylläpitäjän hallinnoima palvelutili", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Ylläpitäjillä on pääsy kaikkiin työkaluihin koko ajan; käyttäjät tarvitsevat työkaluja mallille määritettynä työtilassa.", "Advanced": "Edistynyt", - "Advanced MinerU parsing parameters in JSON format.": "", + "Advanced MinerU parsing parameters in JSON format.": "Edistyneet MinerU jäsennysparametrit JSON muodossa", "Advanced Parameters": "Edistyneet parametrit", "Advanced Params": "Edistyneet parametrit", - "After changing the embedding model, reindex the knowledge base for changes to take effect.": "", + "After changing the embedding model, reindex the knowledge base for changes to take effect.": "Upotusmallin vaihtamisen jälkeen indeksoi tietokanta uudelleen, jotta muutokset tulevat voimaan.", "All": "Kaikki", - "All Chats": "", + "All Chats": "Kaikki keskustelut", "All chats have been unarchived.": "Kaikki keskustelut poistettu arkistosta.", "All day": "Koko päivä", - "All events": "", + "All events": "Kaikki tapahtumat", "All models are now hidden": "Kaikki mallit ovat nyt piilotettu", "All models are now visible": "Kaikki mallit ovat nyt näkyvissä", "All models deleted successfully": "Kaikki mallit poistettu onnistuneesti", - "All shared chats have been unshared.": "", - "All Sources": "", + "All shared chats have been unshared.": "Kaikki jaetut keskustelut eivät ole enää jaettuja.", + "All Sources": "Kaikki lähteet", "All time": "Kokoajalta", "All Users": "Kaikki käyttäjät", - "All users and system events": "", - "Allow artifacts to access same-origin browser APIs inside the sandbox.": "", - "Allow automatic names for new chats.": "", - "Allow browser notifications for completed responses.": "", + "All users and system events": "Kaikki käyttäjät ja järjestelmän tapahtumat", + "Allow artifacts to access same-origin browser APIs inside the sandbox.": "Salli artefaktien käyttää hiekkalaatikon sisällä samaa alkuperää olevia selaimen API:lla.", + "Allow automatic names for new chats.": "Salli automaattiset nimet uusille keskusteluille", + "Allow browser notifications for completed responses.": "Salli selaimen ilmoitukset valmiista vastauksista", "Allow Call": "Salli puhelut", "Allow Chat Controls": "Salli keskustelujen hallinta", "Allow Chat Delete": "Salli keskustelujen poisto", "Allow Chat Edit": "Salli keskustelujen muokkaus", "Allow Chat Export": "Salli keskustelujen vienti", - "Allow Chat Import": "", + "Allow Chat Import": "Salli keskustelujen tuonti", "Allow Chat Params": "Salli keskustelujen parametrit", "Allow Chat Share": "Salli keskustelujen jako", "Allow Chat System Prompt": "Salli keskustelujen järjestelmä kehotteet", "Allow Chat Valves": "Salli keskustelu venttiilit", "Allow Continue Response": "Salli jatka vastausta", - "Allow delegated sub-agents to keep running while the parent chat continues.": "", + "Allow delegated sub-agents to keep running while the parent chat continues.": "Salli delegoitujen aliagenttien pysyä käynnissä samalla kun pääkeskustelu jatkuu.", "Allow Delete Messages": "Salli viestien poisto", "Allow File Upload": "Salli tiedostojen lataus", - "Allow forms inside sandboxed artifact iframes.": "", - "Allow Google Drive as a document source.": "", - "Allow models to run generated code and return execution results.": "", - "Allow models to use the code interpreter tool during chats.": "", + "Allow forms inside sandboxed artifact iframes.": "Salli lomakkeet hiekkalaatikkoon sijoitetuissa artifakti-iframeissa.", + "Allow Google Drive as a document source.": "Salli Google Drive asiakirjalähteeksi", + "Allow models to run generated code and return execution results.": "Salli mallien suorittaa luotua koodia ja palauttaa suoritustulokset.", + "Allow models to use the code interpreter tool during chats.": "Salli mallien käyttää ohjelmatulkkia keskustelujen aikana.", "Allow Multiple Models in Chat": "Salli useampi malli keskustelussa", - "Allow new users to create accounts.": "", + "Allow new users to create accounts.": "Salli uusien käyttäjien luoda tilejä", "Allow non-local voices": "Salli ei-paikalliset äänet", - "Allow OneDrive as a document source.": "", + "Allow OneDrive as a document source.": "Salli OneDrive asiakirjalähteeksi.", "Allow public write access": "Salli julkinen kirjoitusoikeus", "Allow Rate Response": "Salli viestien arviointi", "Allow Regenerate Response": "Salli uudelleen regenerointi", - "Allow Sharing With Groups": "", + "Allow Sharing With Groups": "Salli jakaminen ryhmien kesken", "Allow Sharing With Users": "Salli jakaminen käyttäjien kesken", "Allow Speech to Text": "Salli puhe tekstiksi", "Allow Temporary Chat": "Salli väliaikaiset keskustelut", "Allow Text to Speech": "Salli teksti puheeksi", - "Allow the AI to delegate tasks to sub-agents. Each sub-agent creates a real chat with full tool access. Uses additional LLM calls.": "", + "Allow the AI to delegate tasks to sub-agents. Each sub-agent creates a real chat with full tool access. Uses additional LLM calls.": "Salli tekoälyn delegoida tehtäviä aliagenteille. Jokainen aliagentti luo todellisen keskustelun, jolla on täydet työkalukäyttöoikeudet. Käyttää ylimääräisiä LLM-kutsuja.", "Allow User Location": "Salli käyttäjän sijainti", - "Allow users to access calendar features.": "", - "Allow users to authenticate with an LDAP directory.": "", - "Allow users to configure webhooks from their account.": "", - "Allow users to create accounts through OAuth.": "", - "Allow users to create and manage notes.": "", - "Allow users to create and run automations.": "", - "Allow users to create API keys for programmatic access.": "", - "Allow users to edit existing images.": "", - "Allow users to generate images from prompts.": "", - "Allow users to organize chats into folders.": "", - "Allow users to save memories for more personalized responses.": "", - "Allow users to search the web from chats.": "", - "Allow users to share chats with the Open WebUI community.": "", - "Allow users to use channels for shared conversations.": "", + "Allow users to access calendar features.": "Salli käyttäjien käyttää kalenterin ominaisuuksia", + "Allow users to authenticate with an LDAP directory.": "Salli käyttäjien todentaa itsensä LDAP-hakemistolla.", + "Allow users to authenticate with an OAuth / OIDC provider.": "", + "Allow users to configure webhooks from their account.": "Salli käyttäjien määrittää webhookkeja tililtään.", + "Allow users to create accounts through OAuth.": "Salli käyttäjien luoda tilejä OAuthin kautta.", + "Allow users to create and manage notes.": "Salli käyttäjien luoda ja hallinnoida muistiinpanoja.", + "Allow users to create and run automations.": "Salli käyttäjien luoda ja suorittaa automaatioita.", + "Allow users to create API keys for programmatic access.": "Salli käyttäjien luoda API-avaimia ohjelmallista käyttöä varten.", + "Allow users to edit existing images.": "Salli käyttäjien muokata olemassa olevia kuvia.", + "Allow users to generate images from prompts.": "Salli käyttäjien luoda kuvia kehotteista.", + "Allow users to organize chats into folders.": "Salli käyttäjien järjestää keskusteluja kansioihin.", + "Allow users to save memories for more personalized responses.": "Salli käyttäjien tallentaa muistoja saadakseen henkilökohtaisempia vastauksia.", + "Allow users to search the web from chats.": "Salli käyttäjien etsiä verkosta keskusteluissa.", + "Allow users to share chats with the Open WebUI community.": "Salli käyttäjien jakaa keskusteluja Open WebUI yhteisön kanssa.", + "Allow users to use channels for shared conversations.": "Salli käyttäjien käyttää kanavia jaetuissa keskusteluissa.", "Allow Voice Interruption in Call": "Salli äänen keskeytys puhelussa", "Allow Web Upload": "Salli verkko lataukset", - "Allowed Domains": "", + "Allowed Domains": "Hyväksytyt verkko-osoitteet", "Allowed Endpoints": "Hyväksytyt päätepisteet", "Allowed File Extensions": "Hyväksytyt tiedostomuodot", - "Allowed Roles": "", + "Allowed Roles": "Hyväksytyt roolit", "Already have an account?": "Onko sinulla jo tili?", - "Also bound to {{action}}": "", + "Also bound to {{action}}": "Sidottu myös {{action}}", "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.": "Vaihtoehto top_p:lle, ja sen tavoitteena on varmistaa laadun ja monimuotoisuuden tasapaino. Parametri p edustaa vähimmäistodennäköisyyttä, jonka on oltava tokenin huomioimiseksi suhteessa todennäköisimmän tokenin todennäköisyyteen. Esimerkiksi, kun p=0.05 ja todennäköisin tokenilla on todennäköisyys 0.9, logitit, joiden arvo on alle 0.045, suodatetaan pois.", "Always": "Aina", "Always Collapse Code Blocks": "Pienennä aina koodilohkot", @@ -223,35 +225,36 @@ "and create a new shared link.": "ja luo uusi jaettu linkki.", "Android": "Android", "Anyone": "Kukatahansa", - "API Auth String": "", + "Anyone with the link can view": "", + "API Auth String": "API-autentikointimerkkijono", "API Base URL": "API:n verkko-osoite", "API Key": "API-avain", - "API Key / Token": "", + "API Key / Token": "API-avain / tokeni", "API Key created.": "API-avain luotu.", "API Key Endpoint Restrictions": "API-avaimen päätepiste rajoitukset", - "API key for embedding requests.": "", - "API key sent to Docling.": "", - "API key sent to Mistral OCR.": "", - "API key sent to the external document loader.": "", - "API key sent to the external reranker.": "", - "API key used for MinerU cloud mode.": "", - "API key used to authenticate with Datalab Marker.": "", + "API key for embedding requests.": "API-avain upotuspyyntöjä varten.", + "API key sent to Docling.": "API-avain lähetetty Doclingille.", + "API key sent to Mistral OCR.": "API-avain lähetetty Mistral OCR:lle.", + "API key sent to the external document loader.": "API-avain lähetetty ulkoiselle Document Loader:lle.", + "API key sent to the external reranker.": "API-avain lähetetty ulkoiselle uudelleen sijoittajalle.", + "API key used for MinerU cloud mode.": "API-avain MinerU:n pilvitilaa varten.", + "API key used to authenticate with Datalab Marker.": "Datalab Markerin todentamiseen käytetty API-avain.", "API keys": "API-avaimet", "API Keys": "API-avaimet", "API Mode": "API-moodi", "API Timeout": "API aikakatkaisu", - "API Token": "", - "API token sent to PaddleOCR-vl.": "", + "API Token": "API-tokeni", + "API token sent to PaddleOCR-vl.": "API-avain lähetetty PaddleOCR-vl:lle.", "API Type": "API-tyyppi", - "API URL": "", + "API URL": "API-osoite", "API Version": "API-versio", "API Version is required": "API-versio vaaditaan", - "Append a watermark to assistant responses when configured.": "", + "Append a watermark to assistant responses when configured.": "Lisää vesileima avustajan vastauksiin, kun se on määritetty.", "Application DN": "Sovelluksen DN", "Application DN Password": "Sovelluksen DN-salasana", "applies to all users with the \"user\" role": "koskee kaikkia käyttäjiä, joilla on \"käyttäjä\"-rooli", - "Apply image compression to channel uploads too.": "", - "Apply voice-specific instructions while voice mode is active.": "", + "Apply image compression to channel uploads too.": "Käytä kuvan pakkausta myös kanaviin ladattaviin kuviin.", + "Apply voice-specific instructions while voice mode is active.": "Käytä äänikohtaisia ohjeita, kun äänitila on käytössä.", "April": "huhtikuu", "Archive": "Arkistoi", "Archive All": "Arkistoi kaikki", @@ -269,25 +272,26 @@ "Are you sure you want to delete this memory? This action cannot be undone.": "Haluatko varmasti poistaa muiston? Tätä toimintoa ei voi peruuttaa.", "Are you sure you want to delete this message?": "Haluatko varmasti poistaa tämän viestin?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Haluatko varmasti poistaa tämän version? Alaversiot linkitetään uudelleen tämän version ylätason versioon.", - "Are you sure you want to delete this webhook? This action cannot be undone.": "", + "Are you sure you want to delete this webhook? This action cannot be undone.": "Haluatko varmasti poistaa tämän webhookin? Tätä toimintoa ei voi peruuttaa.", "Are you sure you want to delete this?": "Haluatko varmasti poistää tämän?", - "Are you sure you want to reset all permissions to their default values? You will still need to save to apply the changes.": "", + "Are you sure you want to reset all permissions to their default values? You will still need to save to apply the changes.": "Haluatko varmasti palauttaa kaikki käyttöoikeudet niiden oletusarvoihin? Sinun on silti tallennettava, jotta muutokset tulevat voimaan.", "Are you sure you want to unarchive all archived chats?": "Haluatko varmasti purkaa kaikkien arkistoitujen keskustelujen arkistoinnin?", - "Are you sure you want to unshare all shared chats? This will remove all share links.": "", + "Are you sure you want to unshare all shared chats? This will remove all share links.": "Haluatko varmasti lopettaa kaikkien jaettujen keskustelujen jakamisen? Tämä poistaa kaikki jakolinkit.", "Arena Models": "Arena-mallit", "Artifacts": "Artefaktit", "Asc": "Nouseva", "Ask": "Kysy", "Ask a question": "Kysy kysymys", - "Ask a test question": "", - "Ask this knowledge source a test question": "", + "Ask a test question": "Kysy testikysymys", + "Ask this knowledge source a test question": "Kysy tältä tietolähteeltä testikysymys", "Assistant": "Avustaja", - "Assistant messages": "", + "Assistant messages": "Avustajan viestit", "Async Embedding Processing": "Asynkroninen upotus prosessointi", - "at": "", + "at": "klo", "At time of event": "Tapahtumahetkellä", "Attach File From Knowledge": "Liitä tiedosto tietämyksestä", "Attach Files": "Liitä tiedostoja", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Liitä tietoa", "Attach Notes": "Liitä muistiinpanoja", "Attach Webpage": "Liitä verkkosivu", @@ -297,28 +301,28 @@ "Audio": "Ääni", "August": "elokuu", "Auth": "Todennus", - "Auth Mode": "", - "Auth required": "", + "Auth Mode": "Todennustila", + "Auth required": "Todennus vaaditaan", "Authenticate": "Todentaa", "Authentication": "Todennus", "Auto": "Automaattinen", "Auto (Random)": "Automaattinen (satunnainen)", - "Auto Redirect": "", + "Auto Redirect": "Automaattinen uudelleenohjaus", "Auto-Copy Response to Clipboard": "Kopioi vastaus automaattisesti leikepöydälle", - "Auto-Create Groups": "", + "Auto-Create Groups": "Ryhmien automaattinen luonti", "Auto-Playback Response": "Toista vastaus automaattisesti", "Autocomplete Generation": "Automaattisen täydennyksen luonti", "Autocomplete Generation Input Max Length": "Automaattisen täydennyksen syötteen enimmäispituus", - "Autocomplete Generation Prompt": "", - "Automatic": "", - "Automatic Delivery": "", - "Automatic Events": "", + "Autocomplete Generation Prompt": "Automaattisen täydennyksen luontikehote", + "Automatic": "Automaattinen", + "Automatic Delivery": "Automaattinen toimitus", + "Automatic Events": "Automaattiset tapahtumat", "Automatic1111": "Automatic1111", "AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 verkko-osoite vaaditaan.", "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "Lisää järjestelmätyökaluja automaattisesti natiivissa toimintokutsutilassa (esim. aikaleimat, muisti, keskusteluhistoria, muistiinpanot jne.)", "Automation": "Automaatio", "Automation created": "Automaatio luotu", - "Automation Menu": "", + "Automation Menu": "Automaation valikko", "Automation title": "Automaation otsikko", "Automation triggered": "Automaatio laukaistu", "Automation updated": "Automaatio päivitetty", @@ -327,39 +331,39 @@ "Available models": "Käytettävissä olevat mallit", "Available Skills": "Käytettävissä olevat taidot", "Available Tools": "Käytettävissä olevat työkalut", - "Available variables": "", + "Available variables": "Käytettävissä olevat muuttujat", "available!": "saatavilla!", - "Average messages per active day": "", - "Average tokens per chat": "", + "Average messages per active day": "Keskimääräiset viestit aktiivista päivää kohden", + "Average tokens per chat": "Keskimääräiset tokenit keskustelua kohden", "Away": "Poissa", "Awful": "Kauhea", "Azure AI Speech": "Azure AI Speech", "Azure OpenAI": "Azure OpenAI", - "Azure OpenAI API key.": "", - "Azure OpenAI API version.": "", - "Azure OpenAI endpoint used for embeddings.": "", + "Azure OpenAI API key.": "Azure OpenAI API -avain.", + "Azure OpenAI API version.": "Azure OpenAI API -versio.", + "Azure OpenAI endpoint used for embeddings.": "Azure OpenAI -päätepiste upotuksia varten.", "Azure Region": "Azure-alue", "Back": "Takaisin", - "Background sub-agent finished": "", - "background sub-agents": "", + "Background sub-agent finished": "Taustan aliagentti on valmis", + "background sub-agents": "Taustan aliagentit", "Bad Response": "Huono vastaus", - "Balance semantic and lexical weighting for hybrid search.": "", + "Balance semantic and lexical weighting for hybrid search.": "Tasapainota semanttisten ja leksikaalisten painotusten suhdetta hybridihakua varten.", "Banners": "Bannerit", - "Base DN used when searching for users.": "", + "Base DN used when searching for users.": "Käyttäjien haussa käytetty Base DN.", "Base Model (From)": "Perusmalli (alkaen)", - "Base Model is required.": "", + "Base Model is required.": "Perusmalli on pakollinen.", "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "Malliluettelon välimuisti nopeuttaa käyttöä hakemalla mallit vain käynnistyksen yhteydessä, tai asetusten tallentamisen yhteydessä - nopeampaa, mutta ei välttämättä näytä viimeisimpiä malli muutoksia.", - "Base URL": "", + "Base URL": "Perusverkko-osoite", "Bearer": "Bearer", "before": "ennen", "Being lazy": "Oli laiska", - "Bind DN used for directory search.": "", + "Bind DN used for directory search.": "Hakemiston haussa käytetty Bind DN.", "Bing": "", "Bing Search V7 Endpoint": "Bing Search V7 -päätepisteen osoite", "Bing Search V7 Subscription Key": "Bing Search V7 -tilauskäyttäjäavain", "Bio": "Elämänkerta", "Birth Date": "Syntymäpäivä", - "Blocked Groups": "", + "Blocked Groups": "Estetyt ryhmät", "BM25 Weight": "BM25 paino", "Bocha Search API Key": "Bocha Search API -avain", "Bold": "Lihavointi", @@ -368,7 +372,7 @@ "Brave Search API Key": "Brave Search API -avain", "Break down complex requests into trackable steps": "Pilko monimutkaiset pyynnöt seurattaviin vaiheisiin", "Browse and query knowledge bases": "Selaa ja hae tietokannoista", - "Browser Notifications": "", + "Browser Notifications": "Selaimen ilmoitukset", "Builtin Tools": "Sisäänrakennetut työkalut", "Bullet List": "Luettelo", "Button ID": "Painikkeen ID", @@ -376,7 +380,7 @@ "Button Prompt": "Painikkeen kehote", "by {{name}}": "tekijä {{name}}", "By {{name}}": "Tekijä {{name}}", - "By supporting the project through sponsorship or an enterprise license, you help us stay independent, ship new features faster, improve stability, and grow Open WebUI for the long haul.": "", + "By supporting the project through sponsorship or an enterprise license, you help us stay independent, ship new features faster, improve stability, and grow Open WebUI for the long haul.": "Tukemalla projektia sponsoroimalla tai hankkimalla yrityslisenssin autat meitä pysymään riippumattomina, julkaisemaan uusia ominaisuuksia nopeammin, parantamaan vakautta ja kehittämään Open WebUI:ta pitkäjänteisesti.", "Bypass Embedding and Retrieval": "Ohita upotus ja haku", "Bypass Web Loader": "Ohita verkkolataaja", "Cache Base Model List": "Malli luettelon välimuisti", @@ -388,7 +392,7 @@ "Calendars Public Sharing": "Kalenterien julkinen jakaminen", "Call": "Puhelu", "Call feature is not supported when using Web STT engine": "Puhelutoimintoa ei tueta käytettäessä web-puheentunnistusmoottoria", - "Callback URI registered with the provider.": "", + "Callback URI registered with the provider.": "Palveluntarjoajalle rekisteröity takaisinkutsu-URI.", "Camera": "Kamera", "Cancel": "Peruuta", "Cancel download of {{model}}": "Keskeytä {{model}} lataus", @@ -397,7 +401,7 @@ "Capabilities": "Ominaisuudet", "Capture": "Näyttökuva", "Capture Audio": "Kaappaa ääntä", - "Certificate file used for TLS verification.": "", + "Certificate file used for TLS verification.": "TLS-varmennusta varten käytetty sertifikaattitiedosto.", "Certificate Path": "Varmennepolku", "Change folder icon": "Vaihda kansion kuvake", "Change Password": "Vaihda salasana", @@ -412,7 +416,7 @@ "Channels": "Kanavat", "Character": "Kirjain", "Chat": "Keskustelu", - "Chat actions": "", + "Chat actions": "Keskustelutoiminnot", "Chat archived.": "Keskustelu arkistoitu.", "Chat Background Image": "Keskustelun taustakuva", "Chat Bubble UI": "Keskustelu-pallojen käyttöliittymä", @@ -421,45 +425,49 @@ "Chat deleted.": "Keskustelu poistettu.", "Chat Direction": "Keskustelun suunta", "Chat exported successfully": "Keskustelut viety onnistuneesti", - "Chat forked": "", - "Chat history": "", + "Chat forked": "Keskustelu haarautettu", + "Chat history": "Keskusteluhistoria", "Chat History": "Keskusteluhistoria", "Chat ID": "Keskustelu ID", - "Chat is too short to compact": "", + "Chat is too short to compact": "Keskustelu on liian lyhyt tiivistettäväksi.", "Chat moved successfully": "Keskustelu siirrettiin onnistuneesti", "Chat Permissions": "Keskustelun käyttöoikeudet", "Chat Tags Auto-Generation": "Keskustelutunnisteiden automaattinen luonti", "Chat unshared successfully.": "Keskustelun jako lopetettiin onnistuneesti", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "keskustelut", "Chats": "Keskustelut", + "Chats Open Sharing": "", "Chats Public Sharing": "Keskustelujen julkinen jakaminen", "Check Again": "Tarkista uudelleen", "Check for updates": "Tarkista päivitykset", "Checking for updates...": "Tarkistetaan päivityksiä...", "Choose a model before saving...": "Valitse malli ennen tallentamista...", - "Choose automatic, left-to-right, or right-to-left text flow.": "", - "Choose fallback models for background tasks. Current Model follows the active chat model.": "", - "Choose how extracted text is split before indexing.": "", - "Choose how uploaded documents are parsed before indexing.": "", - "Choose how web result pages are fetched and read.": "", - "Choose the browser voice used for speech output.": "", - "Choose the color theme used by the interface.": "", - "Choose the configured text-to-speech service voice.": "", - "Choose the engine used to read assistant responses aloud.": "", - "Choose the engine used to transcribe voice input.": "", - "Choose the gender value stored on your profile.": "", - "Choose the Kokoro.js voice used for speech output.": "", - "Choose the language used for interface text.": "", - "Choose the local or cloud MinerU API mode.": "", - "Choose the provider used for image edits.": "", - "Choose the provider used for image generation.": "", - "Choose the provider used for web search queries.": "", - "Choose the runtime used by the code interpreter tool.": "", - "Choose the runtime used for generated code blocks.": "", - "Choose the speech provider used for assistant audio output.": "", - "Choose the transcription provider used for audio input.": "", - "Choose whether Enter sends immediately or uses Ctrl+Enter.": "", - "Choose whether the app opens to the default home or chat view.": "", + "Choose automatic, left-to-right, or right-to-left text flow.": "Valitse tekstin suunta: automaattinen, vasemmalta oikealle tai oikealta vasemmalle.", + "Choose fallback models for background tasks. Current Model follows the active chat model.": "Valitse varamallit taustatehtäville. Nykyinen malli seuraa aktiivisen keskustelun mallia.", + "Choose folder": "", + "Choose how extracted text is split before indexing.": "Valitse, miten poimittu teksti jaetaan ennen indeksointia.", + "Choose how uploaded documents are parsed before indexing.": "Valitse, miten ladatut asiakirjat jäsennetään ennen indeksointia.", + "Choose how web result pages are fetched and read.": "Valitse, miten verkkotulossivut haetaan ja luetaan.", + "Choose the browser voice used for speech output.": "Valitse selaimen puheääni puheentuottoa varten.", + "Choose the color theme used by the interface.": "Valitse käyttöliittymässä käytettävä väriteema.", + "Choose the configured text-to-speech service voice.": "Valitse määritetyn puhesynteesipalvelun puheääni.", + "Choose the engine used to read assistant responses aloud.": "Valitse avustajan vastausten ääneen lukemiseen käytettävä moottori.", + "Choose the engine used to transcribe voice input.": "Valitse puheen transkriptioon käytettävä moottori.", + "Choose the gender value stored on your profile.": "Valitse profiiliisi tallennettu sukupuoli.", + "Choose the Kokoro.js voice used for speech output.": "Valitse Kokoro.js:n puheääni puheentuottoa varten.", + "Choose the language used for interface text.": "Valitse käyttöliittymässä käytettävä kieli.", + "Choose the local or cloud MinerU API mode.": "Valitse paikallinen tai pilvipohjainen MinerU API-tila.", + "Choose the provider used for image edits.": "Valitse kuvanmuokkauksiin käytettävä palveluntarjoaja.", + "Choose the provider used for image generation.": "Valitse kuvan luomiseen käytettävä palveluntarjoaja.", + "Choose the provider used for web search queries.": "Valitse verkkohakukyselyihin käytettävä palveluntarjoaja.", + "Choose the runtime used by the code interpreter tool.": "Valitse ohjelmatulkissa käytettävä ajonaikainen ympäristö.", + "Choose the runtime used for generated code blocks.": "Valitse luotujen koodilohkojen käyttämä ajonaikainen ympäristö.", + "Choose the speech provider used for assistant audio output.": "Valitse avustajan äänentuottoa varten käytettävä palveluntarjoaja.", + "Choose the transcription provider used for audio input.": "Valitse äänitulon transkriptioon käytettävä palveluntarjoaja.", + "Choose whether Enter sends immediately or uses Ctrl+Enter.": "Valitse, lähettääkö Enter välittömästi vai edellyttääkö se Ctrl+Enteriä.", + "Choose whether the app opens to the default home or chat view.": "Valitse, avautuuko sovellus oletuskotinäkymään vai keskustelunäkymään.", "Chunk Min Size Target": "Osien vähimmäiskoko", "Chunk Overlap": "Päällekkäisten osien määrä", "Chunk Size": "Osien koko", @@ -472,12 +480,13 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", - "Clear filters to reorder": "", + "Clear": "", + "Clear filters to reorder": "Tyhjennä suodattimet uudelleenjärjestelyä varten", "Clear memory": "Tyhjennä muisti", "Clear Memory": "Tyhjennä Muisti", "Clear search": "Tyhjennä haku", "Clear status": "Tyhjennä tila", - "Clear vector storage and knowledge indexing data.": "", + "Clear vector storage and knowledge indexing data.": "Tyhjennä vektoritallennukset ja tietämyksen indeksointitiedot.", "click here": "klikkaa tästä", "Click here for filter guides.": "Katso suodatinohjeita klikkaamalla tästä.", "Click here for help.": "Klikkaa tästä saadaksesi apua.", @@ -492,7 +501,7 @@ "Click on the user role button to change a user's role.": "Klikkaa käyttäjän roolipainiketta vaihtaaksesi käyttäjän roolia.", "Click to connect": "Klikkaa yhdistääksesi", "Click to copy ID": "Klikkaa kopioidaksesi ID", - "Click to rebind": "", + "Click to rebind": "Klikkaa määrittääksesi uudelleen", "Client ID": "Client ID", "Client Secret": "Client Secret", "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Leikepöydälle kirjoitusoikeus evätty. Tarkista selaimesi asetukset ja myönnä tarvittavat käyttöoikeudet.", @@ -522,38 +531,38 @@ "Code Interpreter Prompt Template": "Ohjelmatulkin kehotemalli", "Collaboration channel where people join as members": "Yhteistyökanava, johon ihmiset liittyvät jäseninä", "Collapse": "Pienennä", - "Collapse code blocks by default.": "", + "Collapse code blocks by default.": "Pienennä koodilohkot oletuksena.", "Collection": "Kokoelma", - "Collection Field": "", + "Collection Field": "Kokoelmakenttä", "Collections": "Kokoelmat", "Color": "Väri", - "Combine semantic and keyword retrieval.": "", + "Combine semantic and keyword retrieval.": "Yhdistä semanttinen haku ja avainsanahaku.", "ComfyUI": "ComfyUI", "ComfyUI Base URL is required.": "ComfyUI verkko-osoite vaaditaan.", "ComfyUI Workflow": "ComfyUI-työnkulku", "ComfyUI Workflow Nodes": "ComfyUI-työnkulun solmut", "Comma separated Node Ids (e.g. 1 or 1,2)": "Pilkulla erotellut Node Id:t (esim. 1 tai 1,2)", - "Comma-separated API paths that API keys can access.": "", - "Comma-separated audio or video MIME types accepted for upload.": "", - "Comma-separated extensions MinerU should handle.": "", - "Comma-separated group names": "", + "Comma-separated API paths that API keys can access.": "Pilkulla erotellut API-polut, joihin API-avaimilla on pääsy.", + "Comma-separated audio or video MIME types accepted for upload.": "Pilkulla erotellut audio- tai video-MIME-tyypit, joita hyväksytään latauksissa.", + "Comma-separated extensions MinerU should handle.": "Pilkulla erotellut tiedostopäätteet, joita MinerU:n pitäisi käsitellä.", + "Comma-separated group names": "Pilkulla erotellut ryhmien nimet", "Comma-separated top-level request parameters this upstream may receive without translation. Use * to allow all captured passthrough params.": "", - "Comma-separated upload extensions. Leave empty for all file types.": "", + "Comma-separated upload extensions. Leave empty for all file types.": "Pilkulla erotellut hyväksytyt tiedostopäätteet. Jätä tyhjäksi, jos haluat sallia kaikki tiedostotyypit.", "command": "komento", "Command": "Komento", - "Commands": "", + "Commands": "Komennot", "Comment": "Kommentti", "Commit Message": "Vahvistusviesti", - "Community": "", + "Community": "Yhteisö", "Community Reviews": "Yhteisön arvostelut", - "Community Sharing": "", - "Compacting context": "", - "Compacting context...": "", - "Compare": "", + "Community Sharing": "Yhteisö jako", + "Compacting context": "Kontekstin pakkaaminen", + "Compacting context...": "Kontekstin pakkaaminen...", + "Compare": "Vertaile", "Comparing with knowledge base...": "Vertaillaan tietokantaan...", "Completions": "Täydennykset", "Compress Images in Channels": "Pakkaa kuvat kanavissa", - "Compress uploaded images before sending or storage.": "", + "Compress uploaded images before sending or storage.": "Pakkaa ladatut kuvat ennen lähettämistä tai tallentamista.", "Computing checksums ({{count}} files)_one": "Tarkistussummien laskenta ({{count}} tiedostoa)_one", "Computing checksums ({{count}} files)_other": "Tarkistussummien laskenta ({{count}} tiedostoa)_other", "Concurrent Requests": "Samanaikaiset pyynnöt", @@ -563,20 +572,21 @@ "Confirm": "Vahvista", "Confirm Password": "Vahvista salasana", "Confirm Prompt from Embed": "Vahvista kehote upotuksesta", + "Confirm recording": "", "Confirm your action": "Vahvista toimintasi", "Confirm your new password": "Vahvista uusi salasanasi", "Confirm Your Password": "Vahvista salasanasi", - "Connect code execution to a Jupyter server endpoint.": "", - "Connect code interpreter to a Jupyter server endpoint.": "", - "Connect to a stable-diffusion-webui server running with the `--api` flag.": "", + "Connect code execution to a Jupyter server endpoint.": "Yhdistä koodin suoritus Jupyter-palvelimen päätepisteeseen.", + "Connect code interpreter to a Jupyter server endpoint.": "Yhdistä ohjelmatulkki Jupyter-palvelimen päätepisteeseen.", + "Connect to a stable-diffusion-webui server running with the `--api` flag.": "Yhdistä stable-diffusion-webui-palvelimeen, joka on käynnissä --api parametrillä.", "Connect to an AI provider to start chatting": "Yhdistä tekoälypalveluntarjoajaan aloittaaksesi keskustelut", "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "Yhdistä Open Terminal -instansseihin selataksesi tiedostoja ja käyttääksesi niitä aina päällä olevina työkaluina. Vain yksi voi olla aktiivinen kerrallaan.", "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "Yhdistä Open Terminal -instansseihin. Kaikilla käyttäjillä on pääsy tiedostojen selaamiseen ja päätetyökaluihin näiden palvelimien kautta.", - "Connect to the ComfyUI server used for generation.": "", - "Connect to the ComfyUI server used for image edits.": "", + "Connect to the ComfyUI server used for generation.": "Yhdistä generointia varten käytettyyn ComfyUI-palvelimeen.", + "Connect to the ComfyUI server used for image edits.": "Yhdistä kuvanmuokkauksiin käytettyyn ComfyUI-palvelimeen.", "Connect to your own OpenAI compatible API endpoints.": "Yhdistä omat OpenAI yhteensopivat API päätepisteet.", "Connect to your own OpenAPI compatible external tool servers.": "Yhdistä omat ulkopuoliset OpenAPI yhteensopivat työkalu palvelimet.", - "Connected": "", + "Connected": "Yhdistetty", "Connected ({{type}})": "Yhdistetty ({{type}})", "Connection failed": "Yhteys epäonnistui", "Connection lost. Reconnecting...": "Yhteys katkaistu. Yhdistetään uudelleen...", @@ -588,32 +598,32 @@ "Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "Rajoittaa päättelyn määrää päättelymalleissa. Tämä soveltuu vain tarjoajiin jotka tukevat päättelyn määrä asetusta.", "Contact Admin for WebUI Access": "Ota yhteyttä ylläpitäjään WebUI-käyttöä varten", "Content": "Sisältö", - "Content Extraction": "", + "Content Extraction": "Sisällönpoiminta", "Content Extraction Engine": "Sisällönpoimintamoottori", - "Content Field": "", + "Content Field": "Sisältökenttä", "Content lengths (character counts only)": "Sisällön pituus (vain merkkimäärä)", - "Context": "", - "Context compacted": "", - "Context Compaction": "", - "Context compaction failed": "", - "Context compaction is disabled": "", - "Context Compaction Prompt": "", - "Context Compaction Threshold": "", + "Context": "Konteksti", + "Context compacted": "Konteksti tiivistetty", + "Context Compaction": "Kontekstin tiivistys", + "Context compaction failed": "Kontekstin tiivistys epäonnistui", + "Context compaction is disabled": "Kontekstin tiivistys on poistettu käytöstä", + "Context Compaction Prompt": "Kontekstin tiivistyksen kehote", + "Context Compaction Threshold": "Kontekstin tiivistyksen kynnys", "Context Tokens": "Konteksti tokenit", - "Continue": "", + "Continue": "Jatka", "Continue Response": "Jatka vastausta", "Continue with {{provider}}": "Jatka palvelulla {{provider}}", "Continue with Email": "Jatka sähköpostilla", "Continue with LDAP": "Jatka LDAP:illa", "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.": "Muokkaa, miten viestin teksti jaetaan puhesynteesipyyntöjä varten. 'Välimerkit' jakaa lauseisiin, 'kappaleet' jakaa kappaleisiin ja 'ei mitään' pitää viestin yhtenä merkkijonona.", - "Control result volume and parallel search requests.": "", + "Control result volume and parallel search requests.": "Säädä hakutulosten määrää ja samanaikaisia hakupyyntöjä.", "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.": "Säätelee generoidun tekstin token-jaksojen toistumista. Korkeampi arvo (esim. 1.5) rankaisee toistoja voimakkaammin, kun taas matalampi arvo (esim. 1.1) on lievempi. Arvolla 1 se on pois päältä.", "Controls": "Ohjaimet", - "Controls how chat tags are inferred.": "", - "Controls how older messages are rewritten into a running summary.": "", + "Controls how chat tags are inferred.": "Ohjaa, miten keskustelutunnisteet päätellään.", + "Controls how older messages are rewritten into a running summary.": "Ohjaa, miten vanhemmat viestit kirjoitetaan uudelleen yhteenvetoon.", "Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "Kontrolloi yhtenäisyyden ja monimuotoisuuden tasapainoa tuloksessa. Pienempi arvo tuottaa kohdennetumman ja johdonmukaisemman tekstin.", "Conversation saved successfully": "Keskustelun tallennus onnistui", - "Convert long pasted text into a file attachment.": "", + "Convert long pasted text into a file attachment.": "Muunna pitkä liite teksti tiedostoliitteeksi.", "Copied": "Kopioitu", "Copied link to clipboard": "Linkki kopioitu leikepöydälle", "Copied shared chat URL to clipboard!": "Jaettu keskustelulinkki kopioitu leikepöydälle!", @@ -628,16 +638,16 @@ "Copy Link": "Kopioi linkki", "Copy Path": "Kopioi polku", "Copy Prompt": "Kopioi kehote", - "Copy rich formatted content instead of plain text.": "", + "Copy rich formatted content instead of plain text.": "Kopioi muotoiltu sisältö tavallisen tekstin sijaan.", "Copy Share Link": "Kopioi jakolinkki", - "Copy the current session token for authenticated requests.": "", - "Copy the latest assistant response when it completes.": "", + "Copy the current session token for authenticated requests.": "Kopioi nykyinen istunnon tunniste todennettuja pyyntöjä varten.", + "Copy the latest assistant response when it completes.": "Kopioi avustajan viimeisin vastaus, kun se on valmis.", "Copy to clipboard": "Kopioi leikepöydälle", "Copy Token": "Kopioi tokeni", "Copy URL": "Kopioi linkki", "Copying to clipboard was successful!": "Kopioiminen leikepöydälle onnistui!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "CORS täytyy olla konfiguroitu palveluntarjoajan toimesta pyyntöjen hyväksymiseksi Open WebUI:sta.", - "Could not load release notes.": "", + "Could not load release notes.": "Julkaisutietojen lataaminen epäonnistui.", "Could not read file.": "Tiedostoa ei voitu lukea.", "CPU": "", "Create": "Luo", @@ -647,54 +657,54 @@ "Create Account": "Luo tili", "Create Admin Account": "Luo ylläpitäjätili", "Create and manage scheduled automations": "Luo ja hallinnoi aikataulutettuja automaatioita", - "Create announcements shown to users in the app.": "", + "Create announcements shown to users in the app.": "Luo sovelluksessa käyttäjille näytettäviä ilmoituksia.", "Create Channel": "Luo kanava", - "Create chat tags from conversation content.": "", + "Create chat tags from conversation content.": "Luo keskustelutunnisteet keskustelun sisällöstä.", "Create Folder": "Luo kansio", "Create Image": "Luo kuva", "Create Knowledge": "Luo tietoa", - "Create missing groups from LDAP groups.": "", + "Create missing groups from LDAP groups.": "Luo puuttuvat ryhmät LDAP-ryhmistä.", "Create missing groups from OAuth claims.": "", "Create Model": "Luo malli", "Create new key": "Luo uusi avain", "Create new secret key": "Luo uusi salainen avain", - "Create Prompt": "", + "Create Prompt": "Luo kehote", "Create scheduled prompts that run automatically on a recurring basis.": "Luo aikataulutettuja kehotteita, jotka suoritetaan automaattisesti toistuvasti.", - "Create your first note from the Create menu.": "", - "Create, copy, or rotate your API key.": "", - "Created": "", + "Create your first note from the Create menu.": "Luo ensimmäinen muistiinpanosi luonti-valikosta.", + "Create, copy, or rotate your API key.": "Luo, kopioi tai vaihda API-avaimesi.", + "Created": "Luotu", "Created at": "Luotu", "Created At": "Luotu", "Created by": "Luonut", "Created by you": "Sinun luomasi", "Created on {{date}}": "Luotu {{date}}", - "Credential used for Document Intelligence.": "", - "Credentials used to authenticate with the Jupyter server.": "", + "Credential used for Document Intelligence.": "Tunnistetiedot, joita käytetään Document Intelligence -palvelussa.", + "Credentials used to authenticate with the Jupyter server.": "Jupyter-palvelimen todentamiseen käytetyt tunnistetiedot.", "CSV Import": "CSV-tuonti", "Ctrl+Enter to Send": "Ctrl+Enter lähetys", - "Current": "", + "Current": "Nykyinen", "Current Model": "Nykyinen malli", "Current Password": "Nykyinen salasana", - "Current streak": "", + "Current streak": "Nykyinen putki", "Custom": "Mukautettu", "Custom color": "Mukautettu väri", "Custom description enabled": "Muokautetut kuvaukset käytössä", "Custom Gender": "Muu sukupuoli", - "Custom message shown while an account waits for approval.": "", + "Custom message shown while an account waits for approval.": "Mukautettu viesti, joka näytetään tilin odottaessa hyväksyntää.", "Custom Parameter Name": "Mukautetun parametrin nimi", "Custom Parameter Value": "Mukautetun parametrin arvo", - "Custom permissions": "", - "Custom range": "", - "Custom title shown while an account waits for approval.": "", + "Custom permissions": "Mukautetut käyttöoikeudet", + "Custom range": "Mukautettu alue", + "Custom title shown while an account waits for approval.": "Mukautettu otsikko, joka näytetään tilin odottaessa hyväksyntää.", "Daily": "Päivittäin", - "Daily at": "", + "Daily at": "Päivittäin", "Daily Messages": "Päivittäiset viestit", "Danger Zone": "Vaara-alue", "Dark": "Tumma", "Data Controls": "Datan hallinta", "Database": "Tietokanta", "Datalab Marker API": "Datalab Marker API", - "Datalab Marker service endpoint used for document parsing.": "", + "Datalab Marker service endpoint used for document parsing.": "Datalab Marker -päätepiste asiakirjojen jäsentämistä varten.", "Date Modified": "Muokkauspäivämäärä", "Day": "Päivä", "DD/MM/YYYY": "DD/MM/YYYY", @@ -719,10 +729,11 @@ "Default to ALL": "Oletus KAIKKI", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Segmentoitu haku on oletuksena kohdennettua ja relevanttia sisällön poimimista varten. Tätä suositellaan useimmissa tapauksissa.", + "Default Upload Mode": "", "Default User Role": "Oletuskäyttäjärooli", - "Default webhook": "", - "Defines the behavior used for spoken conversations.": "", - "Delegate focused work to parallel sub-agents": "", + "Default webhook": "Oletus webhook", + "Defines the behavior used for spoken conversations.": "Määrittelee puhutuissa keskusteluissa käytetyn käyttäytymisen.", + "Delegate focused work to parallel sub-agents": "Delegoi kohdennettu työ rinnakkaisille aliagenteille", "Delete": "Poista", "Delete {{name}}": "Poista {{name}}", "Delete a model": "Poista malli", @@ -749,7 +760,7 @@ "Delete skill?": "Poista taito?", "delete this link": "poista tämä linkki", "Delete tool?": "Haluatko varmasti poistaa tämän työkalun?", - "Delete uploaded files from the upload directory.": "", + "Delete uploaded files from the upload directory.": "Poista ladatut tiedostot lataushakemistosta.", "Delete User": "Poista käyttäjä", "Delete Version": "Poista versio?", "Deleted": "Poistettu", @@ -766,7 +777,8 @@ "Description": "Kuvaus", "Deselect": "Poista valinta", "Detect Artifacts Automatically": "Tunnista artefaktit automaattisesti", - "Detect generated artifacts and show them in the artifact workspace.": "", + "Detect generated artifacts and show them in the artifact workspace.": "Tunnista luodut artefaktit ja näytä ne artefaktien työtilassa.", + "Detected Variables": "", "Dictate": "Sanele", "Didn't fully follow instructions": "Ei noudattanut ohjeita täysin", "Direct": "Suora", @@ -780,12 +792,12 @@ "Directory name": "Hakemiston nimi", "Directory renamed.": "Hakemisto uudelleennimetty.", "Directory selection was cancelled": "Hakemiston valinta keskeytettiin", - "Disable all": "", + "Disable all": "Poista kaikki käytöstä", "Disable All": "Poista kaikki käytöstä", "Disable Code Interpreter": "Poista Koodin suoritus käytöstä", "Disable Image Extraction": "Poista kuvien poiminta käytöstä", - "Disable Image Generation": "", - "Disable Web Search": "", + "Disable Image Generation": "Poista kuvagenerointi käytöstä", + "Disable Web Search": "Poista verkkohaku käytöstä", "Disabled": "Ei käytössä", "Disconnect OAuth": "Katkaise OAuth", "Discover a function": "Löydä toiminto", @@ -802,47 +814,48 @@ "Display Chat Title in Tab": "Näytä keskustelu otiskko välilehdessä", "Display Emoji in Call": "Näytä hymiöitä puhelussa", "Display Multi-model Responses in Tabs": "Näytä usean mallin vastaukset välilehdissä", - "Display name for this LDAP connection.": "", - "Display name shown for the OAuth provider.": "", + "Display name for this LDAP connection.": "Tämän LDAP-yhteyden näyttönimi.", + "Display name shown for the OAuth provider.": "OAuth-palveluntarjoajan näyttönimi.", "Display the Username Instead of You in the Chat": "Näytä käyttäjänimi keskustelussa \"Sinä\" -tekstin sijaan", "Displays citations in the response": "Näyttää lähdeviitteet vastauksessa", "Displays status updates (e.g., web search progress) in the response": "Näyttä tilapäivityksiä (esim. verkkohaku) vastauksissa", - "Do not extract images from PDFs during Marker processing.": "", + "Do not extract images from PDFs during Marker processing.": "Älä poimi kuvia PDF-tiedostoista Marker-käsittelyn aikana.", "Do not install functions from sources you do not fully trust.": "Älä asenna toimintoja lähteistä, joihin et luota täysin.", "Do not install tools from sources you do not fully trust.": "Älä asenna työkaluja lähteistä, joihin et luota täysin.", "Do you want to sync your usage stats with Open WebUI Community?": "Haluatko jakaa käyttötilastosi Open WebUI yhteisön kanssa?", "Docling": "Docling", "Docling Parameters": "Docling parametrit", - "Docling Server URL": "", + "Docling Server URL": "Docling palvelimen verkko-osoite", "Docling Server URL required.": "Docling palvelimen verkko-osoite vaaditaan.", - "Docling service endpoint used for parsing.": "", + "Docling service endpoint used for parsing.": "Docling -päätepiste jäsentämistä varten.", "Document": "Asiakirja", "Document ID Field": "", "Document Intelligence": "Document Intelligence", "Document Intelligence endpoint required.": "Document Intelligence pääte vaaditaan", - "Document Intelligence endpoint used for parsing.": "", + "Document Intelligence endpoint used for parsing.": "Document Intelligence -päätepiste jäsentämistä varten.", "Document Intelligence Model": "Document Intelligence malli", - "Document Loader URL": "", + "Document Loader URL": "Document Loader verkko-osoite", "Documentation": "Dokumentaatio", "Documents": "Dokumentit", "does not make any external connections, and your data stays securely on your locally hosted server.": "ei tee ulkoisia yhteyksiä, ja tietosi pysyvät turvallisesti paikallisesti isännöidyllä palvelimellasi.", "Domain Filter List": "Verkko-osoitteiden suodatuslista", - "Don't fetch random pipelines from sources you don't trust.": "", + "Don't fetch random pipelines from sources you don't trust.": "Älä hae satunnaisia putkistoja lähteistä, joihin et luota.", "Don't have an account?": "Eikö sinulla ole tiliä?", "Don't like the style": "En pidä tyylistä", "Done": "Valmis", "Download": "Lataa", "Download & Delete": "Lataa ja poista", - "Download all users as CSV.": "", + "Download all users as CSV.": "Lataa kaikki käyttäjät CSV:nä.", "Download as JSON": "Lataa JSON:na", "Download as SVG": "Lataa SVG:nä", "Download canceled": "Lataus peruutettu", - "Download every user's chat history as JSON.": "", - "Download the application database when supported.": "", - "Download the current admin configuration as JSON.": "", - "Download your chat history as a JSON export.": "", + "Download every user's chat history as JSON.": "Lataa kaikkien käyttäjien keskusteluhistoria JSON:na.", + "Download failed": "", + "Download the application database when supported.": "Lataa sovelluksen tietokanta, kun tuki on saatavilla.", + "Download the current admin configuration as JSON.": "Lataa nykyinen ylläpitäjän määritys JSON:na.", + "Download your chat history as a JSON export.": "Lataa keskusteluhistoriasi JSON:na.", "Downloading stats...": "Ladataa tilastoja...", - "Drag to reorder": "", + "Drag to reorder": "Raahaa uudelleenjärjestelyä varten", "Draw": "Piirros", "Drop any files here to upload": "Pudota tähän ladattavat tiedostot", "Drop files here": "Pudota tiedostot tähän", @@ -878,14 +891,15 @@ "Edit Default Permissions": "Muokkaa oletuskäyttöoikeuksia", "Edit Folder": "Muokkaa kansiota", "Edit Image": "Kuvan muokkaus", - "Edit Knowledge Connection": "", + "Edit Knowledge Connection": "Muokkaa tietokantayhteyttä", "Edit Last Message": "Muokkaa viimeisintä viestiä", "Edit Memory": "Muokkaa muistia", "Edit Prompt": "Muokkaa kehotetta", "Edit Terminal Connection": "Muokkaa pääteyhteyttä", "Edit User": "Muokkaa käyttäjää", "Edit User Group": "Muokkaa käyttäjäryhmää", - "Edit webhook": "", + "Edit User Variable": "", + "Edit webhook": "Muokkaa webhookia", "Edit workflow.json content": "Muokkaa workflow.json sisältöä", "edited": "muokattu", "Eject": "Poista", @@ -893,8 +907,8 @@ "ElevenLabs": "ElevenLabs", "Email": "Sähköposti", "Email Claim": "", - "Email domains allowed to sign in with OAuth.": "", - "Email shown in the pending account overlay.": "", + "Email domains allowed to sign in with OAuth.": "Sähköpostiverkkotunnukset, joilla voi kirjautua OAuthin kautta.", + "Email shown in the pending account overlay.": "Sähköpostiosoite, joka näytetään tilin odottaessa hyväksyntää.", "Embedding": "Upotus", "Embedding Batch Size": "Upotuksen eräkoko", "Embedding Concurrent Requests": "Samanaikaiset upotuspyynnöt", @@ -902,28 +916,29 @@ "Embedding Model Engine": "Upotusmallin moottori", "Emoji": "Emoji", "Emojis": "Emojit", - "Empty": "", + "Empty": "Tyhjä", "Empty message": "Tyhjä viesti", "Enable All": "Ota kaikki käyttöön", - "Enable background sub-agents": "", + "Enable background sub-agents": "Ota käyttöön taustan aliagentit", "Enable Code Execution": "Ota koodin suoritus käyttöön", "Enable Code Interpreter": "Ota ohjelmatulkki käyttöön", - "Enable Image Generation": "", - "Enable Keyboard Shortcuts": "", + "Enable Image Generation": "Ota kuvagenerointi käyttöön", + "Enable Keyboard Shortcuts": "Ota näppäimistön pikakomennot käyttöön", "Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Ota Memory Locking (mlock) käyttöön estääksesi mallidatan vaihtamisen pois RAM-muistista. Tämä lukitsee mallin työsivut RAM-muistiin, varmistaen että niitä ei vaihdeta levylle. Tämä voi parantaa suorituskykyä välttämällä sivuvikoja ja varmistamalla nopean tietojen käytön.", "Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Ota Memory Mapping (mmap) käyttöön ladataksesi mallidataa. Tämä vaihtoehto sallii järjestelmän käyttää levytilaa RAM-laajennuksena käsittelemällä levytiedostoja kuin ne olisivat RAM-muistissa. Tämä voi parantaa mallin suorituskykyä sallimalla nopeamman tietojen käytön. Kuitenkin se ei välttämättä toimi oikein kaikissa järjestelmissä ja voi kuluttaa huomattavasti levytilaa.", "Enable Message Queue": "Ota viestijono käyttöön", "Enable Mirostat sampling for controlling perplexity.": "", - "Enable sub-agents": "", - "Enable Web Search": "", + "Enable sub-agents": "Ota aliagentit käyttöön", + "Enable Web Search": "Ota verkkohaku käyttöön", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Käytä, poista käytöstä, tai kustomoi mallin päättely tageja. \"Käytä\" käyttää oletus tageja, \"Ei käytössä\" ottaa päätely tagit pois käytöstä, ja \"Mukautettu\" antaa sinun määritellä aloitus ja lopetus tagit.", "Enabled": "Käytössä", + "End call": "", "End Tag": "Lopetus tagi", - "Endpoint": "", + "Endpoint": "Päätepiste", "Endpoint URL": "Päätepiste verkko-osoite", "Enforce Temporary Chat": "Pakota väliaikaiset keskustelut", "Enhance": "Paranna", - "Enhance this note and update it.": "", + "Enhance this note and update it.": "Paranna tätä muistiota ja päivitä se.", "Enrich Hybrid Search Text": "Rikasta hybridihakutekstiä", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Varmista, että CSV-tiedostossasi on 4 saraketta tässä järjestyksessä: Nimi, Sähköposti, Salasana, Rooli.", "Enter {{role}} message here": "Kirjoita {{role}}-viesti tähän", @@ -931,7 +946,7 @@ "Enter a watermark for the response. Leave empty for none.": "Kirjoita vastauksen vesileima. Jätä tyhjäksi, jos et halua mitään.", "Enter additional headers in JSON format": "Kirjoita lisä ylätunnisteita JSON muodossa", "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "Kirjoita lisäotsikot JSON-muodossa (esim. {\"X-Custom-Header\": \"value\"}", - "Enter additional OpenAI-compatible TTS request parameters as JSON.": "", + "Enter additional OpenAI-compatible TTS request parameters as JSON.": "Kirjoita lisä OpenAI yhteensopivat TTS pyynnön parametrit JSON muodossa.", "Enter additional parameters in JSON format": "Kirjoita lisäparametrit JSON muodossa", "Enter api auth string (e.g. username:password)": "Kirjoita API-todennusmerkkijono (esim. käyttäjätunnus:salasana)", "Enter Application DN": "Kirjoita sovelluksen DN", @@ -944,8 +959,8 @@ "Enter Chunk Min Size Target": "Kirjoita osien vähimmäiskoko", "Enter Chunk Overlap": "Syötä osien päällekkäisyys", "Enter Chunk Size": "Syötä osien koko", - "Enter Client ID": "", - "Enter Client Secret": "", + "Enter Client ID": "Kirjoita Client ID", + "Enter Client Secret": "Kirjoita Client Secret", "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Syötä pilkulla erottaen \"token:bias_value\" parit (esim. 5432:100, 413:-100)", "Enter content for the pending user info overlay. Leave empty for default.": "Kirjoita odottavien käyttäjien infon tekstisisältö. Käytä oletusta jättämällä tyhjäksi.", "Enter coordinates (e.g. 51.505, -0.09)": "Kirjoita kordinaatit (esim. 51.505, -0.09)", @@ -983,11 +998,11 @@ "Enter Jupyter URL": "Kirjoita Jupyter verkko-osoite", "Enter Kagi Search API Key": "Kirjoita Kagi Search API -avain", "Enter Key Behavior": "Enter näppäimen käyttäytyminen", - "Enter language": "", + "Enter language": "Kirjoita kieli", "Enter language codes": "Kirjoita kielikoodit", "Enter Linkup API Key": "Kirjoita Linkup API-avain", - "Enter Microsoft Web IQ API Base URL": "", - "Enter Microsoft Web IQ API Key": "", + "Enter Microsoft Web IQ API Base URL": "Kirjoita Microsoft Web IQ API verkko-osoite", + "Enter Microsoft Web IQ API Key": "Kirjoita Microsoft Web IQ API-avain", "Enter MinerU API Key": "Kirjoita MinerU API-avain", "Enter Mistral API Base URL": "Kirjoita Mistral API verkko-osoite", "Enter Mistral API Key": "Kirjoita Mistral API-avain", @@ -1006,7 +1021,7 @@ "Enter prompt here.": "Kirjoita kehote tähän.", "Enter proxy URL (e.g. https://user:password@host:port)": "Kirjoita välityspalvelimen verkko-osoite (esim. https://käyttäjä:salasana@host:portti)", "Enter reasoning effort": "Kirjoita päättelyn määrä", - "Enter Redirect URI": "", + "Enter Redirect URI": "Kirjoita uudelleen-ohjaus URI", "Enter Score": "Kirjoita pistemäärä", "Enter SearchApi API Key": "Kirjoita SearchApi API -avain", "Enter SearchApi Engine": "Kirjoita SearchApi-moottori", @@ -1016,7 +1031,7 @@ "Enter SerpApi API Key": "Kirjoita SerpApi API -avain", "Enter SerpApi Engine": "Valitse SerpApi Moottori", "Enter Serper API Key": "Kirjoita Serper API -avain", - "Enter SERPHouse API Key": "", + "Enter SERPHouse API Key": "Kirjoita SERPHouse API -avain", "Enter Serply API Key": "Kirjoita Serply API -avain", "Enter Serpstack API Key": "Kirjoita Serpstack API -avain", "Enter server host": "Kirjoita palvelimen isäntänimi", @@ -1035,8 +1050,8 @@ "Enter the URL to import": "Kirjoita tuotavan verkko-osoite", "Enter Tika Server URL": "Kirjoita Tika Server URL", "Enter to Send": "Enter lähetys", - "Enter token threshold": "", - "Enter Tokenizer Model": "", + "Enter token threshold": "Kirjoita tokenkynnys", + "Enter Tokenizer Model": "Kirjoita tokenizer-malli", "Enter Top K": "Kirjoita Top K", "Enter Top K Reranker": "Kirjoita Top K uudelleen sijoittaja", "Enter URL (e.g. http://127.0.0.1:7860/)": "Kirjoita verkko-osoite (esim. http://127.0.0.1:7860/)", @@ -1062,7 +1077,7 @@ "Enter Your Role": "Kirjoita roolisi", "Enter Your Username": "Kirjoita käyttäjätunnuksesi", "Enterprise licenses also include dedicated support, customization options, and more, at a fraction of the cost of building and maintaining this stack internally.": "", - "Enterprise licensing": "", + "Enterprise licensing": "Yrityslisensointi", "Entra ID": "Entra ID", "Environment Variables": "Ympäristömuuttujat", "Ephemeral": "Tilapäinen", @@ -1078,20 +1093,20 @@ "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "Virhe: Malli '{{modelId}}' on jo käytössä. Valitse toinen ID jatkaaksesi.", "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "Virhe: Mallin ID ei voi olla tyhjä. Kirjoita ID jatkaaksesi.", "Evaluations": "Arvioinnit", - "Event": "", + "Event": "Tapahtuma", "Event created": "Tapahtuma luotu", "Event deleted": "Tapahtuma poistettu", - "Event names may change as Open WebUI evolves. Use broad patterns like user.* for integrations that should continue across new related events.": "", + "Event names may change as Open WebUI evolves. Use broad patterns like user.* for integrations that should continue across new related events.": "Tapahtumien nimet voivat muuttua Open WebUI:n kehittyessä. Käytä laajoja kuvioita, kuten user.*, integraatioille, joiden tulisi toimia myös uusien, niihin liittyvien tapahtumien yhteydessä.", "Event title": "Tapahtuman otsikko", "Event updated": "Tapahtuma päivitetty", - "Events": "", + "Events": "Tapahtumat", "Every {{count}} hours_one": "", "Every {{count}} hours_other": "", "Every {{count}} minutes_one": "", "Every {{count}} minutes_other": "", - "Every minute": "", + "Every minute": "Joka minuutti", "Exa API Key": "Exa API -avain", - "Example": "", + "Example": "Esimerkki", "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Esimerkki: (&(objectClass=inetOrgPerson)(uid=%s))", "Example: ALL": "Esimerkki: KAIKKI", "Example: mail": "Esimerkki: posti", @@ -1101,7 +1116,7 @@ "Exclude": "Jätä pois", "Execute code": "Suorita koodi", "Execute code for analysis": "Suorita koodi analysointia varten", - "Executing {{NAME}}...": "", + "Executing {{NAME}}...": "Suoritetaan {{NAME}}...", "Expand": "Laajenna", "Experimental": "Kokeellinen", "Explain": "Selitä", @@ -1113,30 +1128,30 @@ "Export chat (.json)": "Vie keskustelu (.json)", "Export Chats": "Vie keskustelut", "Export Config": "Vie asetukset", - "Export JSON": "", + "Export JSON": "Vie JSON", "Export Models": "Vie mallit", "Export Prompts": "Vie kehotteet", - "Export Skills": "", + "Export Skills": "Vie taidot", "Export to CSV": "Vie CSV-tiedostoon", "Export Tools": "Vie työkalut", "External": "Ulkoiset", - "External connection not found.": "", + "External connection not found.": "Ulkoista yhteyttä ei löytynyt.", "External Document Loader URL required.": "Ulkoisen Document Loader:n verkko-osoite on vaaditaan.", - "External Knowledge Source": "", - "External Knowledge Sources": "", - "External reranker endpoint.": "", - "External service endpoint used to load document content.": "", + "External Knowledge Source": "Ulkoinen tietolähde", + "External Knowledge Sources": "Ulkoiset tietolähteet", + "External reranker endpoint.": "Ulkoinen reranker-päätepiste.", + "External service endpoint used to load document content.": "Ulkoinen palvelu -päätepiste asiakirjojen sisällön lataamista varten.", "External Task Model": "Ulkoinen työmalli", - "External Tool Servers": "", - "External vectors must be generated with the same embedding model configured in Open WebUI.": "", + "External Tool Servers": "Ulkoiset työkalu palvelimet", + "External vectors must be generated with the same embedding model configured in Open WebUI.": "Ulkoiset vektorit täytyy generoida samalla upotusmallilla, joka on konfiguroitu Open WebUI:ssä.", "External Web Loader API Key": "Ulkoinen Web Loader API-avain", "External Web Loader URL": "Ulkoinen Web Loader verkko-osoite", "External Web Search API Key": "Ulkoinen Web Search API-avain", "External Web Search URL": "Ulkoinen Web Search verkko-osoite", - "Extract action items from this note.": "", - "Extract images from PDFs so OCR can process image-only pages.": "", + "Extract action items from this note.": "Poimi toimenpiteet tästä muistiinpanosta.", + "Extract images from PDFs so OCR can process image-only pages.": "Poimi kuvat PDF-tiedostoista, jotta OCR voi käsitellä kuvapohjaisia sivuja.", "Fade Effect for Streaming Text": "Häivytystehoste suoratoistetulle tekstille", - "Fade streaming text as it arrives.": "", + "Fade streaming text as it arrives.": "Häivytä suoratoistoteksti sitä mukaa kun se saapuu.", "Failed to add file.": "Tiedoston lisääminen epäonnistui.", "Failed to add members": "Jäsenten lisääminen epäonnistui", "Failed to archive chat.": "Keskustelun arkistointi epäonnistui.", @@ -1147,44 +1162,45 @@ "Failed to connect to {{URL}} terminal server": "Yhdistäminen {{URL}} päätepalvelimeen epäonnistui", "Failed to copy link": "Linkin kopiointi epäonnistui", "Failed to create API Key.": "API-avaimen luonti epäonnistui.", - "Failed to create chat": "", + "Failed to create chat": "Keskustelun luonti epäonnistui", "Failed to delete calendar": "Kalenterin poistaminen epäonnistui", "Failed to delete note": "Muistiinpanon poistaminen epäonnistui", - "Failed to delete webhook": "", + "Failed to delete webhook": "Webhookin poistaminen epäonnistui", "Failed to disconnect": "Yhteyden katkaiseminen epäonnistui", "Failed to download image": "Kuvan lataaminen epäonnistui", "Failed to extract content from the file: {{error}}": "Tiedoston sisällön pomiminen epäonnistui: {{error}}", "Failed to extract content from the file.": "Tiedoston sisällön pomiminen epäonnistui.", "Failed to fetch models": "Mallien hakeminen epäonnistui", - "Failed to fork chat": "", + "Failed to fork chat": "Keskustelun haarauttaminen epäonnistui", "Failed to generate title": "Otsikon luonti epäonnistui", "Failed to import models": "Mallien tuonti epäonnistui", - "Failed to load chat": "", + "Failed to load chat": "Keskustelun lataaminen epäonnistui", "Failed to load chat preview": "Keskustelun esikatselun lataaminen epäonnistui", "Failed to load DOCX file. Please try downloading it instead.": "DOCX-tiedoston avaaminen epäonnistui. Yritä ladata se sen sijaan.", "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV tiedoston lataaminen epäonnistui. Yritä ladata se sen sijaan.", "Failed to load file content.": "Tiedoston sisällön lataaminen epäonnistui.", "Failed to load Interface settings": "Käyttöliittymän asetusten lataaminen epäonnistui", - "Failed to load policy: {{error}}": "", + "Failed to load policy: {{error}}": "Käytäntöjen lataaminen epäonnistui: {{error}}", "Failed to load PPTX file. Please try downloading it instead.": "PPTX-tiedoston lataaminen epäonnistui. Yritä ladata se sen sijaan.", - "Failed to load usage": "", + "Failed to load usage": "Käytön lataaminen epäonnistui", "Failed to move chat": "Keskustelun siirto epäonnistui", "Failed to process URL: {{url}}": "Verkko-osoitteen käsittely epäonnistui: {{url}}", "Failed to read clipboard contents": "Leikepöydän sisällön lukeminen epäonnistui", - "Failed to refresh terminals: {{error}}": "", + "Failed to refresh terminals: {{error}}": "Päätteiden päivitys epäonnistui: {{error}}", "Failed to remove member": "Jäsenen poistaminen epäonnistui", "Failed to render diagram": "Diagrammin renderöinti epäonnistui", "Failed to render visualization": "Visualisoinnin renderöinti epäonnistui", + "Failed to save chat variables": "", "Failed to save connections": "Yhteyksien tallentaminen epäonnistui", "Failed to save conversation": "Keskustelun tallentaminen epäonnistui", "Failed to save models configuration": "Mallien määrityksen tallentaminen epäonnistui", "Failed to save policy: {{error}}": "Käytännön tallentaminen epäonnistui: {{error}}", "Failed to save terminal servers": "Päätepalvelimien tallennus epäonnistui", - "Failed to save webhook": "", + "Failed to save webhook": "Webhookin tallentaminen epäonnistui", "Failed to unshare chat.": "Jaon lopettaminen epäonnistui.", "Failed to update settings": "Asetusten päivittäminen epäonnistui", "Failed to update status": "Tilan päivittäminen epäonnistui", - "Failed to update webhook": "", + "Failed to update webhook": "Webhookin päivittäminen epäonnistui", "Failed to upload file.": "Tiedoston lataaminen epäonnistui.", "Features": "Ominaisuudet", "Features Permissions": "Ominaisuuksien käyttöoikeudet", @@ -1195,7 +1211,7 @@ "Feedback Details": "Palautteen tiedot", "Feel free to add specific details": "Voit lisätä tarkempia tietoja", "Female": "Nainen", - "Fetch page contents without proxy environment variables.": "", + "Fetch page contents without proxy environment variables.": "Hae sivun sisältö ilman välityspalvelimen ympäristömuuttujia.", "Fetch URL Content Length Limit": "Noudetun URL-osoitteen sisällön pituusraja", "File": "Tiedosto", "File added successfully.": "Tiedosto lisätty onnistuneesti.", @@ -1217,8 +1233,8 @@ "File uploaded successfully": "Tiedosto ladattiin onnistuneesti", "Filename": "Tiedostonimi", "Files": "Tiedostot", - "Fill the required fields first.": "", - "Fill the source fields and test query first.": "", + "Fill the required fields first.": "Täytä ensin pakolliset kentät.", + "Fill the source fields and test query first.": "Täytä ensin lähdekentät ja testikysely.", "Filter": "Suodata", "Filter is now globally disabled": "Suodatin on nyt poistettu käytöstä globaalisti", "Filter is now globally enabled": "Suodatin on nyt otettu käyttöön globaalisti", @@ -1241,7 +1257,8 @@ "Folder options": "Kansion asetukset", "Folder updated successfully": "Kansio päivitettiin onnistuneesti", "Folders": "Kansiot", - "Folders Sharing": "", + "Folders Sharing": "Kansioiden jako", + "Follow assistant responses as they are generated.": "", "Follow up": "Jatkokysymykset", "Follow Up Generation": "Jatkokysymysten luonti", "Follow Up Generation Prompt": "Jatkokysymysten luonti kehote", @@ -1250,13 +1267,13 @@ "Followed instructions perfectly": "Noudatti ohjeita täydellisesti", "for placeholders": "", "Force OCR": "Pakota OCR", - "Forking chat...": "", + "Forking chat...": "Haarautetaan keskustelua...", "Form": "Lomake", "Format Lines": "Muotoile rivit", - "Format lines to detect inline math and styles.": "", - "Format Markdown in previews and compact content surfaces.": "", - "Format Markdown syntax in assistant responses.": "", - "Format Markdown syntax in your own messages.": "", + "Format lines to detect inline math and styles.": "Muotoile rivit inline-matematiikan ja tyylien tunnistamiseksi.", + "Format Markdown in previews and compact content surfaces.": "Muotoile Markdown esikatseluissa ja tiiviissä sisältöpinnoissa.", + "Format Markdown syntax in assistant responses.": "Muotoile Markdown avustajan vastauksissa.", + "Format Markdown syntax in your own messages.": "Muotoile Markdown-syntaksi omissa viesteissäsi.", "Formatting may be inconsistent from source.": "Muotoilu voi poiketa alkuperäisestä.", "Forward": "Eteenpäin", "Forwards system user OAuth access token to authenticate": "Välittää järjestelmä käyttäjän OAuth tunniste todennuksessa", @@ -1271,14 +1288,14 @@ "Function imported successfully": "Toiminnon tuonti onnistui", "Function is now globally disabled": "Toiminto on nyt poistettu käytöstä globaalisti", "Function is now globally enabled": "Toiminto on nyt otettu käyttöön globaalisti", - "Function Menu": "", + "Function Menu": "Toiminnon valikko", "Function Name": "Toiminnon nimi", "Function Name Filter List": "Toiminnon nimi Suodatinluettelo", - "Function starter": "", + "Function starter": "Toiminnon käynnistin", "Function updated successfully": "Toiminto päivitetty onnistuneesti", "Functions": "Toiminnot", "Functions allow arbitrary code execution.": "Toiminnot sallivat mielivaltaisen koodin suorittamisen.", - "Functions can execute arbitrary code.": "", + "Functions can execute arbitrary code.": "Toiminnot voivat suorittaa mielivaltaista koodia.", "Functions imported successfully": "Toiminnot tuotu onnistuneesti", "Gemini": "Gemini", "Gemini API Key is required.": "Gemini API -avain on vaaditaan.", @@ -1287,12 +1304,13 @@ "General": "Yleinen", "Generate": "Luo", "Generate an image": "Luo kuva", - "Generate an image prompt before sending the request.": "", + "Generate an image prompt before sending the request.": "Luo kuvakehote ennen pyynnön lähettämistä.", "Generate and edit images": "Luo ja muokkaa kuvia", - "Generate chat titles automatically from conversation content.": "", + "Generate message pair": "", + "Generate chat titles automatically from conversation content.": "Luo keskusteluotsikot automaattisesti keskustelun sisällöstä.", "Generate Message Pair": "Luo viesti pari", - "Generate suggested follow-up prompts after responses.": "", - "Generate tags for chats automatically.": "", + "Generate suggested follow-up prompts after responses.": "Luo ehdotettuja jatkokysymyksiä vastausten jälkeen.", + "Generate tags for chats automatically.": "Luo tunnisteet keskusteluille automaattisesti.", "Generated Image": "Luo kuva", "Generated images will appear here": "Luodut kuvat näkyvät tässä", "Generating search query": "Luodaan hakukyselyä", @@ -1302,7 +1320,7 @@ "Get information on {{name}} in the UI": "Hae tietoja {{name}} -nimestä käyttöliittymässä", "Get started": "Aloita", "Get started with {{WEBUI_NAME}}": "Aloita käyttämään {{WEBUI_NAME}}:iä", - "GitHub URL": "", + "GitHub URL": "GitHub-osoite", "Global": "Yleinen", "Good Response": "Hyvä vastaus", "Google": "", @@ -1312,9 +1330,9 @@ "Gravatar": "Gravatar", "Grid": "Ruudukko", "Grokipedia": "", - "group": "", - "Group": "", - "Group assigned to new users by default.": "", + "group": "ryhmä", + "Group": "Ryhmä", + "Group assigned to new users by default.": "Ryhmä, joka annetaan uusille käyttäjille oletuksena.", "Group Attribute": "", "Group Channel": "Ryhmäkanava", "Group Claim": "", @@ -1322,14 +1340,14 @@ "Group deleted successfully": "Ryhmä poistettu onnistuneesti", "Group Description": "Ryhmän kuvaus", "Group Mapping": "", - "Group multi-model responses into tabs.": "", + "Group multi-model responses into tabs.": "Ryhmittele usean mallin vastaukset välilehdiksi.", "Group Name": "Ryhmän nimi", "Group updated successfully": "Ryhmä päivitetty onnistuneesti", "groups": "ryhmät", "Groups": "Ryhmät", - "Guides how the assistant formats tool and function calls.": "", - "Guides inline completions while users type a message.": "", - "Guides the suggestions shown after an assistant response.": "", + "Guides how the assistant formats tool and function calls.": "Ohjeistaa, miten avustaja muotoilee työkalujen ja funktioiden kutsut.", + "Guides inline completions while users type a message.": "Ohjaa inline-täydennyksiä, kun käyttäjät kirjoittavat viestiä.", + "Guides the suggestions shown after an assistant response.": "Ohjaa avustajan vastauksen jälkeen näytettäviä ehdotuksia.", "H1": "H1", "H2": "H2", "H3": "H3", @@ -1338,7 +1356,7 @@ "Headers": "Ylätunnisteet", "Headers must be a valid JSON object": "Ylätunnisteet täytyy olla kelvollisia JSON-objekteja", "Height": "Korkeus", - "Height in pixels to compress images to. Leave empty for no compression.": "", + "Height in pixels to compress images to. Leave empty for no compression.": "Korkeus pikseleinä, johon kuvat pakataan. Jätä tyhjäksi, jos et halua pakkausta.", "Hello, {{name}}": "Hei, {{name}}", "Help": "Ohje", "Help the community discover great models": "Auta yhteisöä löytämään upeita malleja", @@ -1367,7 +1385,7 @@ "ID cannot contain \":\" or \"|\" characters": "ID ei voi sisältää \":\" tai \"|\" kirjaimia", "ID copied to clipboard": "ID kopioitu leikepöydälle", "Identity audit": "", - "Idle only": "", + "Idle only": "Vain lepotila", "Idle Timeout": "Aikakatkaisu", "iframe Sandbox Allow Forms": "Salli lomakkeet iframe hiekkalaatikossa", "iframe Sandbox Allow Same Origin": "Salli iframe hiekkalaatikko samasta alkuperästä", @@ -1387,45 +1405,45 @@ "Image Size": "Kuvan koko", "Images": "Kuvat", "Import": "Tuo", - "Import admin configuration from a JSON export file.": "", - "Import chat history from a JSON export file.": "", + "Import admin configuration from a JSON export file.": "Tuo ylläpitäjän määritys JSON-vientitiedostosta.", + "Import chat history from a JSON export file.": "Tuo keskusteluhistoria JSON-vientitiedostosta.", "Import Chats": "Tuo keskustelut", "Import Config": "Tuo asetukset", "Import From Link": "Tuo verkko-osoitteesta", - "Import JSON": "", + "Import JSON": "Tuo JSON", "Import Models": "Tuo mallit", "Import Prompts": "Tuo kehotteet", - "Import Skills": "", + "Import Skills": "Tuo taidot", "Import successful": "Tuonti onnistui", "Import Tools": "Tuo työkalut", - "Import txt/md": "", + "Import txt/md": "Tuo txt/md", "Important Update": "Tärkeä päivitys", - "Imported automations successfully": "", - "Imported notes successfully": "", + "Imported automations successfully": "Automaatiot tuotiin onnistuneesti", + "Imported notes successfully": "Muistiinpanot tuotiin onnistuneesti", "Inactive": "Toimeton", "Include": "Sisällytä", - "Include saved memories in the system context.": "", - "Include voices that are not provided by a local speech service.": "", - "Increase contrast for controls and input surfaces.": "", + "Include saved memories in the system context.": "Sisällytä tallennetut muistot järjestelmän kontekstiin.", + "Include voices that are not provided by a local speech service.": "Sisällytä puheääniä, joita paikallinen puhesynteesipalvelu ei tarjoa.", + "Increase contrast for controls and input surfaces.": "Lisää kontrastia ohjaus- ja kentille.", "Increase UI Scale": "Kasvata käyttöliittymän kokoa", "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Kuinka nopeasti algoritmi mukautuu generoidun tekstin palautteeseen. Alempi oppimisnopeus hidastaa mukautumista, kun taas nopeampi oppimisnopeus tekee algoritmistä reagoivamman.", "Info": "Tiedot", "Initials": "Nimikirjaimet", - "Inject entire documents as context for comprehensive processing.": "", + "Inject entire documents as context for comprehensive processing.": "Upota koko asiakirja kontekstiin kattavaa käsittelyä varten.", "Inject file content into conversation context": "Upota tiedostosisältö keskustelun kontekstiin", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Upota koko sisältö kontekstiin kattavaa käsittelyä varten. Tätä suositellaan monimutkaisille kyselyille.", - "Inject the entire content as context for comprehensive processing.": "", + "Inject the entire content as context for comprehensive processing.": "Upota koko sisältö kontekstiin kattavaa käsittelyä varten.", "Input": "Tekstikenttä", "Input Key (e.g. text, unet_name, steps)": "Syötteen arvo (esim. text, unet_namme, steps)", "Input Variables": "Syötteen muuttujat", "Insert": "Lisää", "Insert Follow-Up Prompt to Input": "Lisää jatkokysymys syötteeseen", - "Insert into note": "", + "Insert into note": "Lisää muistiinpanoon", "Insert Prompt as Rich Text": "Lisää kehote RTF-muodossa", - "Insert selected follow-up prompts directly into the composer.": "", + "Insert selected follow-up prompts directly into the composer.": "Lisää valitut jatkokysymykset suoraan syötteeseen.", "Insert Suggestion Prompt to Input": "Lisää kehote ehdotus syötteeseen", - "Install": "", - "Installing": "", + "Install": "Asenna", + "Installing": "Asennetaan", "Instant Auto-Send After Voice Transcription": "Automaattinen lähetys äänitunnistuksen jälkeen", "Instructions": "Ohjeistukset", "Integration": "Integrointi", @@ -1434,7 +1452,7 @@ "Interface Settings Access": "Käyttöliittymän asetusten käyttöoikeus", "Invalid file format.": "Virheellinen tiedostomuoto.", "Invalid JSON file": "Virheellinen JSON tiedosto", - "Invalid JSON format": "", + "Invalid JSON format": "Virheellinen JSON muotoilu", "Invalid JSON format for ComfyUI Edit Workflow.": "Virheellinen JSON muotoilu ComfyUI Edit työnkululle", "Invalid JSON format for ComfyUI Workflow.": "Virhellinen JSON muotoilu ComfyUI työnkululle.", "Invalid JSON format for Parameters": "Virheellinen JSON muotoilu parametreille", @@ -1449,25 +1467,26 @@ "join our Discord for help.": "liity Discordiimme saadaksesi apua.", "JSON": "JSON", "JSON Base64": "", - "JSON options passed to Marker for advanced parsing behavior.": "", + "JSON options passed to Marker for advanced parsing behavior.": "Markerille välitettävät JSON-asetukset edistyneeseen jäsentämiseen.", "JSON Preview": "JSON-esikatselu", "JSON Spec": "JSON Spec", "July": "heinäkuu", "June": "kesäkuu", "Jupyter Auth": "Jupyter todennus", - "Jupyter Password": "", - "Jupyter Token": "", + "Jupyter Password": "Jupyter salasana", + "Jupyter Token": "Juypyter token", "Jupyter URL": "Jupyter verkko-osoite", "JWT Expiration": "JWT-vanheneminen", "JWT Token": "JWT-token", "Kagi Search API Key": "Kagi Search API -avain", - "Keep current webhook URL": "", + "Keep current webhook URL": "Käytä nykyistä webhook-verkko-osoitetta", "Keep Follow-Up Prompts in Chat": "Säilytä jatkokysymys kehotteet keskustelussa", - "Keep generated follow-up prompts visible in the chat.": "", + "Keep generated follow-up prompts visible in the chat.": "Säilytä luodut jatkokysymys kehotteet keskustelussa.", "Keep in Sidebar": "Pidä sivupalkissa", "Key": "Avain", "Key is required": "Avain vaaditaan", - "Keyboard": "", + "key_name": "", + "Keyboard": "Näppäimistö", "Knowledge": "Tietämys", "Knowledge Access": "Tiedon käyttöoikeus", "Knowledge Base": "Tietokanta", @@ -1479,8 +1498,8 @@ "Knowledge Name": "Tietokannan nimi", "Knowledge Public Sharing": "Tietokannan julkinen jakaminen", "Knowledge Sharing": "Tietokannan jakaminen", - "Knowledge source created.": "", - "Knowledge source updated.": "", + "Knowledge source created.": "Tietolähde luotu.", + "Knowledge source updated.": "Tietolähde päivitetty.", "Knowledge updated successfully": "Tietokanta päivitetty onnistuneesti", "Kokoro.js (Browser)": "Kokoro.js (selain)", "Kokoro.js Dtype": "Kokoro.js Dtype", @@ -1495,14 +1514,14 @@ "Last Active": "Viimeksi aktiivinen", "Last Modified": "Viimeksi muokattu", "Last reply": "Viimeksi vastattu", - "Last run": "", + "Last run": "Viimeisin suoritus", "LDAP": "LDAP", - "LDAP attribute containing the user group memberships.": "", - "LDAP attribute used as the user email address.": "", - "LDAP attribute used as the username.": "", - "LDAP filter used to match signing-in users.": "", - "LDAP server hostname or IP address.": "", - "LDAP server port.": "", + "LDAP attribute containing the user group memberships.": "LDAP-määrite, joka sisältää käyttäjäryhmien jäsenyyksiä.", + "LDAP attribute used as the user email address.": "LDAP-määrite, jota käytetään käyttäjän sähköpostiosoitteena.", + "LDAP attribute used as the username.": "LDAP-määrite, jota käytetään käyttäjätunnuksena.", + "LDAP filter used to match signing-in users.": "LDAP-suodatin, jota käytetään sisäänkirjautuvien käyttäjien tunnistamiseen.", + "LDAP server hostname or IP address.": "LDAP-palvelimen isäntänimi tai IP-osoite.", + "LDAP server port.": "LDAP-palvelimen portti.", "Leaderboard": "Tulosluettelo", "Learn More": "Lue lisää", "Learn more about Open Terminal": "Lue lisää Open Terminal", @@ -1510,7 +1529,7 @@ "Learn more about Voxtral transcription.": "Lue lisää Voxtral transkriptio:sta", "Leave a public review for {{modelName}}": "Jätä julkinen arvostelu {{modelName}}", "Leave empty for no compression": "Jätä tyhjäksi, jos et halua pakkausta", - "Leave empty for the built-in default.": "", + "Leave empty for the built-in default.": "Jätä tyhjäksi käyttääksesi sisäänrakennetun oletusarvon.", "Leave empty for unlimited": "Rajaton tyhjänä", "Leave empty to include all models from \"{{url}}\" endpoint": "Jätä tyhjäksi sisällyttääksesi \"{{url}}\" päätepisteen mallit", "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Jätä tyhjäksi sisällyttääksesi \"{{url}}/api/tags\" päätepisteen mallit", @@ -1520,51 +1539,51 @@ "Leave empty to use the default config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)": "Jätä tyhjäksi käyttääksesi oletuskokoonpanoa tai anna kelvollinen JSON-tiedosto (katso https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)", "Leave empty to use the default model (voxtral-mini-latest).": "Jätä tyhjäks käyttääksesi oletusmallia (voxtral-mini-latest)", "Leave empty to use the default prompt, or enter a custom prompt": "Jätä tyhjäksi käyttääksesi oletuskehotetta tai kirjoita mukautettu kehote", - "Leave empty to use the default prompt, or enter a custom prompt.": "", + "Leave empty to use the default prompt, or enter a custom prompt.": "Jätä tyhjäksi käyttääksesi oletuskehotetta tai kirjoita mukautettu kehote.", "Leave model field empty to use the default model.": "Jätä malli kenttä tyhjäksi käyttääksesi oletus mallia.", "Legacy": "Legacy", - "Let speech interrupt the assistant during a voice call.": "", - "Let users rate assistant responses.": "", + "Let speech interrupt the assistant during a voice call.": "Anna puheen keskeyttää avustaja äänipuhelun aikana.", + "Let users rate assistant responses.": "Salli käyttäjien arvioida avustajan vastauksia.", "lexical": "leksikaalinen", "License": "Lisenssi", "Lifecycle JSON": "", - "Lifetime tokens": "", + "Lifetime tokens": "Elinaikaiset tokenit", "Lift List": "Nostolista", "Light": "Vaalea", - "Limit API keys to configured endpoints.": "", + "Limit API keys to configured endpoints.": "Rajoita API-avaimet määritettyihin päätepisteisiin.", "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "Rajoita samanaikaisia hakukyselyitä. 0 = rajoittamaton (oletus). Aseta arvoon 1 peräkkäistä suoritusta varten (suositellaan API-rajapinnoille, joilla on tiukat nopeusrajoitukset, kuten Brave-ilmaistaso).", - "Limit how much draft text is sent for suggestion generation.": "", - "Limit parallel web loader requests.": "", - "Link OAuth sign-ins to existing accounts with the same email.": "", + "Limit how much draft text is sent for suggestion generation.": "Rajoita lähetettävän luonnostekstin määrää ehdotusten generointia varten.", + "Limit parallel web loader requests.": "Rajoita samanaikaisia verkkolataajan pyyntöjä.", + "Link OAuth sign-ins to existing accounts with the same email.": "Yhdistä OAuthin kautta tehdyt kirjautumiset olemassa oleviin tileihin, joilla on sama sähköpostiosoite.", "Linkup API Key": "Linkup API-avain", "List": "Lista", "List calendars, search, create, update, and delete calendar events": "Listaa kalenterit, hae, luo, päivitä ja poista kalenteritapahtumia", "Listening...": "Kuuntelee...", + "LiteLLM": "", "Live": "Live", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Kielimallit voivat tehdä virheitä. Tarkista tärkeät tiedot.", "Loaded": "Ladattu", "Loader": "Lataaja", "Loading Kokoro.js...": "Ladataan Kokoro.js...", - "Loading policy...": "", - "Loading release notes...": "", + "Loading policy...": "Ladataan käytäntöä...", + "Loading release notes...": "Julkaisutietoja ladataan...", "Loading...": "Ladataan...", "local": "paikallinen", "Local": "Paikallinen", "Local Task Model": "Paikallinen työmalli", "Location": "Sijainti", "Location access not allowed": "Ei pääsyä sijaintitietoihin", - "Longest active chat": "", - "Longest streak": "", + "Longest active chat": "Pisin aktiivinen keskustelu", + "Longest streak": "Pisin putki", "Lost": "Mennyt", "Low": "Matala", "LTR": "LTR", "Made by Open WebUI Community": "Tehnyt OpenWebUI-yhteisö", - "Make Default": "", + "Make Default": "Aseta oletukseksi", "Make password visible in the user interface": "Näytä salasana käyttöliittymässä", - "Make Private": "", - "Make Public": "", + "Make Private": "Aseta yksityiseksi", + "Make Public": "Aseta julkiseksi", "Male": "Mies", "Manage": "Hallitse", "Manage Connections": "Hallitse yhteyksiä", @@ -1581,29 +1600,31 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "maaliskuu", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown-otsikkotekstin jakaja", "Max background": "", - "Max concurrent": "", - "Max iterations": "", + "Max concurrent": "Samanaikaisten enimmäismäärä", + "Max iterations": "Iteraatioiden enimmäismäärä", "Max output": "", "Max Speakers": "Puhujien enimmäismäärä", "Max tokens to retrieve (1024-32768, default 8192)": "Haettavien tokenien enimmäismäärä (1024–32768, oletus 8192)", "Max Upload Count": "Latausten enimmäismäärä", "Max Upload Size": "Latausten enimmäiskoko", "Maximum characters to return from fetched URLs. Leave empty for no limit.": "Maksimimerkkimäärä haetuista URL-osoitteista. Jätä tyhjäksi, jos et halua rajoitusta.", - "Maximum concurrent embedding requests. Set to 0 for unlimited.": "", - "Maximum file size in MB. Leave empty for unlimited.": "", + "Maximum concurrent embedding requests. Set to 0 for unlimited.": "Samanaikaisten upotuspyyntöjen enimmäismäärä. Aseta 0 rajattomaksi.", + "Maximum file size in MB. Leave empty for unlimited.": "Tiedoston enimmäiskoko megatavuina. Jätä tyhjäksi, jos et halua rajoitusta.", "Maximum number of files allowed per folder.": "Kansiota kohden sallittujen tiedostojen enimmäismäärä.", "Maximum number of files per folder is {{max}}.": "Tiedostojen enimmäismäärä kansiossa on {{max}}.", - "Maximum number of files that can be used at once in chat.": "", - "Maximum number of hybrid results sent to the reranker.": "", - "Maximum number of retrieved chunks returned to the model.": "", + "Maximum number of files that can be used at once in chat.": "Keskustelussa kerralla käytettävien tiedostojen enimmäismäärä.", + "Maximum number of hybrid results sent to the reranker.": "Uudelleenlajittelijalle lähetettävien hybriditulosten enimmäismäärä.", + "Maximum number of retrieved chunks returned to the model.": "Mallille palautettavien haettujen tekstipalasten enimmäismäärä.", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Enintään 3 mallia voidaan ladata samanaikaisesti. Yritä myöhemmin uudelleen.", - "Maximum runtime in seconds before execution is stopped.": "", - "Maximum size for each text chunk.": "", - "Maximum time in seconds to wait for MinerU API responses.": "", - "Maximum time to wait while loading web content.": "", + "Maximum runtime in seconds before execution is stopped.": "Enimmäissuoritusaika sekunteina ennen suorituksen pysäyttämistä.", + "Maximum size for each text chunk.": "Kunkin tekstipalasen enimmäiskoko.", + "Maximum time in seconds to wait for MinerU API responses.": "Maksimi odotusaika sekunteina MinerU API:n vastauksille.", + "Maximum time to wait while loading web content.": "Maksimi odotusaika verkkosisällön latautuessa.", "May": "toukokuu", "MBR": "MBR", "MCP": "MCP", @@ -1619,18 +1640,18 @@ "Memory added successfully": "Muisti lisätty onnistuneesti", "Memory cleared successfully": "Muisti tyhjennetty onnistuneesti", "Memory deleted successfully": "Muisti poistettu onnistuneesti", - "Memory System Context": "", + "Memory System Context": "Muistijärjestelmän konteksti", "Memory updated successfully": "Muisti päivitetty onnistuneesti", - "Merge Accounts by Email": "", - "Merge chunks smaller than this threshold when possible. Set to 0 to disable merging.": "", + "Merge Accounts by Email": "Yhdistä tilit sähköpostin perusteella", + "Merge chunks smaller than this threshold when possible. Set to 0 to disable merging.": "Yhdistä tämän kynnyksen alittavat lohkot, kun mahdollista. Aseta arvoon 0 poistaaksesi yhdistämisen käytöstä.", "Merge Responses": "Yhdistä vastaukset", "Merged Response": "Yhdistetty vastaus", "Message": "Viesti", "Message counts and response timestamps": "Viestien määrä ja vastausten aikaleimat", "Message counts are based on assistant responses.": "Viestien määrä perustuu avustajan vastauksiin.", - "Message Rating": "", + "Message Rating": "Viesti arviot", "Message rating should be enabled to use this feature": "Tämän toiminnon käyttämiseksi viestiarviointi on otettava käyttöön", - "Message shown before web search runs.": "", + "Message shown before web search runs.": "Viesti, joka näytetään ennen verkkohakua.", "Message text...": "Viestin teksti...", "messages": "viestit", "Messages": "Viestit", @@ -1641,19 +1662,18 @@ "Microsoft OneDrive (work/school)": "", "Microsoft Web IQ API Base URL": "", "Microsoft Web IQ API Key": "", - "min": "", + "min": "minimi", "MinerU": "MinerU", - "MinerU API endpoint for the selected mode.": "", + "MinerU API endpoint for the selected mode.": "MinerU API-päätepiste valitulle tilalle.", "MinerU API Key required for Cloud API mode.": "MinerU API-avain vaaditaan pilvi API:ssa", "Mistral OCR": "Mistral OCR", "Mistral OCR API Key required.": "Mistral OCR api-avain vaaditaan", - "Mistral OCR service endpoint.": "", + "Mistral OCR service endpoint.": "Mistral OCR -palvelun päätepiste.", "MistralAI": "MistralAI", "Mo_day_of_week": "", "Model": "Malli", "Model '{{modelName}}' has been successfully downloaded.": "Malli '{{modelName}}' ladattiin onnistuneesti.", "Model '{{modelTag}}' is already in queue for downloading.": "Malli '{{modelTag}}' on jo jonossa ladattavaksi.", - "Model {{modelId}} not found": "Malli {{modelId}} ei löytynyt", "Model {{modelName}} deleted successfully": "Malli {{modelName}} poistettu onnistuneesti", "Model {{modelName}} is not vision capable": "Malli {{modelName}} ei kykene näkökykyyn", "Model {{name}} is now {{status}}": "Malli {{name}} on nyt {{status}}", @@ -1661,43 +1681,43 @@ "Model {{name}} is now visible": "Malli {{name}} on nyt näkyvissä", "Model accepts file inputs": "Malli hyväksyy tiedostosyötteet", "Model accepts image inputs": "Malli hyväksyy kuvasyötteitä", - "Model added to pinned models": "", - "Model added to selected models": "", + "Model added to pinned models": "Malli lisättiin kiinnitettyihin malleihin", + "Model added to selected models": "Malli lisättiin valittuihin malleihin", "Model can access Open Terminal for command execution and file management": "Malli voi käyttää Open Terminal-toimintoa komentojen suorittamiseen ja tiedostojen hallintaan.", "Model can execute code and perform calculations": "Malli voi suorittaa koodia ja laskelmia", "Model can generate images based on text prompts": "Malli voi luoda kuvia tekstikehotteiden perusteella", "Model can search the web for information": "Malli voi hakea tietoa verkosta", "Model Capabilities": "Mallin ominaisuudet", "Model created successfully!": "Malli luotu onnistuneesti!", - "Model Defaults": "", + "Model Defaults": "Mallin oletukset", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Mallin tiedostojärjestelmäpolku havaittu. Mallin lyhytnimi vaaditaan päivitykseen, ei voida jatkaa.", "Model Filtering": "Mallin suodatus", "Model ID": "Mallin tunnus", "Model ID is required.": "Mallin tunnus on pakollinen", "Model IDs": "Mallitunnukset", - "Model is now private": "", - "Model is now public": "", + "Model is now private": "Malli on nyt yksityinen", + "Model is now public": "Malli on nyt julkinen", "Model Name": "Mallin nimi", "Model name already exists, please choose a different one": "Mallin nimi on jo olemassa, valitse toinen nimi.", "Model Name is required.": "Mallin nimi on pakollinen", - "Model name used by Document Intelligence.": "", + "Model name used by Document Intelligence.": "Mallin nimi, jota käytetään Document Intelligence -palvelussa.", "Model names and usage frequency": "Mallien nimet ja käyttötiheys", "Model not found": "Mallia ei löytynyt", "Model not selected": "Mallia ei ole valittu", - "Model order saved successfully": "", - "Model parameters": "", + "Model order saved successfully": "Mallin järjestys tallennettu onnistuneesti", + "Model parameters": "Mallin parametrit", "Model Parameters": "Mallin parametrit", "Model Params": "Mallin parametrit", "Model Permissions": "Mallin käyttöoikeudet", - "Model removed from pinned models": "", - "Model removed from selected models": "", + "Model removed from pinned models": "Malli poistettiin kiinnitettyjen malleista", + "Model removed from selected models": "Malli poistettiin valittujen malleista", "Model responses or outputs": "Mallin vastaukset tai tuotokset", "Model unloaded successfully": "Malli purettu onnistuneesti", "Model updated successfully": "Malli päivitetty onnistuneesti", "Model Usage": "Mallin käyttö", - "Model used to generate embeddings. Reindex knowledge after changing this.": "", - "Model used to rerank retrieved results.": "", - "Model-specific context compaction thresholds cannot exceed this token limit.": "", + "Model used to generate embeddings. Reindex knowledge after changing this.": "Malli, jota käytetään upotusten luomiseen. Uudelleindeksoi tietämyksen tämän muuttamisen jälkeen.", + "Model used to rerank retrieved results.": "Malli, jota käytetään haettujen tulosten uudelleenjärjestämiseen.", + "Model-specific context compaction thresholds cannot exceed this token limit.": "Mallikohtaiset kontekstin tiivistysraja-arvot eivät saa ylittää tätä token-rajaa.", "Model(s) do not support file upload": "Malli(t) ei tue tiedostojen lataamista", "Modelfile Content": "Mallitiedoston sisältö", "Models": "Mallit", @@ -1708,16 +1728,16 @@ "Models Sharing": "Mallien jako", "Mojeek": "", "Mojeek Search API Key": "Mojeek Search API -avain", - "Monday – Friday": "", + "Monday – Friday": "Maanantai - Perjantai", "Month": "Kuukausi", "Monthly": "Kuukausittain", "More": "Lisää", "More Concise": "Lyhyemmin", "More options": "Lisää vaihtoehtoja", "More Options": "Lisää vaihtoehtoja", - "Most used tools": "", + "Most used tools": "Useimmin käytetyt työkalut", "Move": "Siirrä", - "Move every chat into the archive after confirmation.": "", + "Move every chat into the archive after confirmation.": "Siirrä jokainen keskustelu arkistoon vahvistuksen jälkeen.", "Moved {{name}}": "Siirretty {{name}}", "Multipart Upload": "", "Mute": "Mykistä", @@ -1729,13 +1749,13 @@ "Name your knowledge base": "Anna tietokannalle nimi", "Name, prompt, and model are required": "Nimi, kehote ja malli ovat pakollisia", "Native": "Natiivi", - "Native mode (default) leverages the model's built-in tool-calling capabilities. Legacy mode works with a wider range of models by calling tools once before execution via prompt injection.": "", + "Native mode (default) leverages the model's built-in tool-calling capabilities. Legacy mode works with a wider range of models by calling tools once before execution via prompt injection.": "Natiivitila (oletus) hyödyntää mallin sisäänrakennettuja työkalukutsutoimintoja. Legacy-tila toimii laajemman mallivalikoiman kanssa kutsumalla työkaluja kerran ennen suoritusta kehote injektoinnin avulla.", "Never": "Ei koskaan", "New": "Uusi", "New Button": "Uusi painike", "New calendar": "Uusi kalenteri", "New Calendar": "Uusi kalenteri", - "New chat": "", + "New chat": "Uusi keskustelu", "New Chat": "Uusi keskustelu", "New directory": "Uusi hakemisto", "New Directory": "Uusi hakemisto", @@ -1745,25 +1765,28 @@ "New Group": "Uusi ryhmä", "New Note": "Uusi muistiinpano", "New Password": "Uusi salasana", - "New Sign Ups": "", + "New Sign Ups": "Uudet rekisteröitymiset", "New Temporary Chat": "Uusi väliaikainen keskustelu", "New Terminal": "Uusi pääte", "New Tool": "Uusi työkalu", "New Webhook": "Uusi Webhook", "new-channel": "uusi-kanava", "Next message": "Seuraava viesti", - "Next page": "", + "Next month": "", + "Next page": "Seuraava sivu", "Next run": "Seuraava suoritus", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Ei käyttöoikeuksia. Yksityinen sinulle.", - "No actions found": "", + "No actions found": "Toimintoja ei löytynyt", "No activity data": "Ei aktiivisuustietoja", "No additional headers are sent unless configured.": "", "No authentication": "Ei todennusta", "No automations found": "Automaatioita ei löytynyt", - "No chat alerts": "", - "No chat history": "", - "No chat to compact": "", - "No chat to fork": "", + "No chat alerts": "Ei keskusteluilmoituksia", + "No chat history": "Ei keskusteluhistoriaa", + "No chat to compact": "Ei keskustelua tiivistettäväksi", + "No chat to fork": "Ei keskustelua haaroitettavaksi", "No chats found": "Keskuteluja ei löytynyt", "No chats found for this user.": "Käyttäjän keskusteluja ei löytynyt.", "No chats found.": "Keskusteluja ei löytynyt", @@ -1773,17 +1796,18 @@ "No conversation to save": "Ei tallennettavaa keskustelua", "No data": "Ei dataa", "No data found": "Dataa ei löytynyt", - "No description": "", + "No description": "Ei kuvausta", "No distance available": "Etäisyyttä ei saatavilla", - "No event webhooks configured.": "", + "No event webhooks configured.": "Tapahtuma-webhookeja ei ole määritetty.", "No expiration can pose security risks.": "Vanhenemisen laittamatta jättäminen voi altistaa tietoturvariskeille.", - "No external knowledge sources configured.": "", + "No external knowledge sources configured.": "Ei ulkoisia tietolähteitä määritettynä.", "No feedback found": "Ei palautetta", "No file selected": "Tiedostoa ei ole valittu", "No files found": "Tiedostoja ei löytynyt", "No files in this knowledge base.": "Tässä tietokannassa ei ole tiedostoja.", "No files yet. Upload files or run Python code to create them.": "Ei vielä tiedostoja. Lataa tiedostoja tai suorita Python-koodia niiden luomiseksi.", - "No filters found": "", + "No filters found": "Suodattimia ei löytynyt", + "No folders": "", "No functions found": "Toimintoja ei löytynyt", "No groups found": "Ryhmiä ei löytynyt", "No history available": "Historiaa ei saatavilla", @@ -1794,25 +1818,25 @@ "No knowledge bases found.": "Tietokantoja ei löytynyt.", "No knowledge found": "Tietoa ei löytynyt", "No limit": "Ei rajoituksia", - "No matches": "", - "No model data": "", + "No matches": "Ei osumia", + "No model data": "Ei malli dataa", "No model IDs": "Ei mallitunnuksia", - "No model usage found": "", + "No model usage found": "Mallin käyttöä ei löytynyt", "No models accessible": "Malleihin ei ole käyttöoikeutta.", "No models available": "Malleja ei saatavilla", "No models found": "Malleja ei löytynyt", "No models selected": "Malleja ei ole valittu", "No Notes": "Ei muistiinpanoja", "No notes found": "Muistiinpanoja ei löytynyt", - "No notification targets configured.": "", + "No notification targets configured.": "Ilmoituskohteita ei ole määritetty.", "No one": "Kukaan", "No output items": "Ei tulosteita", "No pinned messages": "Ei kiinnitettyjä viestejä", "No prompts found": "Kehotteita ei löytynyt", - "No Repeat": "", + "No Repeat": "Ei uudelleen toistoa", "No results": "Ei tuloksia", "No results found": "Ei tuloksia", - "No runs yet": "", + "No runs yet": "Ei vielä suorituksia", "No search query generated": "Hakukyselyä ei luotu", "No servers detected": "Palvelimia ei havaittu", "No skills found": "Taitoja ei löytynyt", @@ -1824,31 +1848,32 @@ "No tool server connections configured.": "Työkalupalvelinyhteyksiä ei ole määritetty.", "No tools accessible": "Työkaluihin ei ole käyttöoikeutta.", "No tools found": "Työkaluja ei löytynyt", - "No usage data found": "", + "No usage data found": "Käyttötietoja ei löytynyt", + "No user variables configured.": "", "No users were found.": "Käyttäjiä ei löytynyt.", "No valves": "Ei venttiileitä", "No valves to update": "Ei venttiileitä päivitettäväksi", "No webhooks yet": "Ei vielä webhookeja", "Node Ids": "Node id:t", "None": "Ei mikään", - "Not configured": "", + "Not configured": "Ei määritetty", "Not factually correct": "Ei faktuaalisesti oikein", "Not helpful": "Ei hyödyllinen", "Not Registered": "Ei kirjautunut", "Not scheduled": "Ei aikataulutettu", "Note": "Muistiinpano", "Note deleted successfully": "Muistiinpano poistettiin onnistuneesti", - "Note Menu": "", + "Note Menu": "Muistiinpanovalikko", "Notes": "Muistiinpanot", "Notes Public Sharing": "Muistiinpanojen julkinen jako", "Notes Sharing": "Muistiinpanojen jako", - "Nothing to compact": "", + "Nothing to compact": "Ei mitään tiivistettävää", "Notification Sound": "Ilmoitusääni", - "Notification Targets": "", + "Notification Targets": "Ilmoituskohteet", "Notifications": "Ilmoitukset", "November": "marraskuu", - "Number of items processed per embedding batch.": "", - "Number of results processed per reranking batch.": "", + "Number of items processed per embedding batch.": "Yhdessä upotuserässä käsiteltävien kohteiden määrä.", + "Number of results processed per reranking batch.": "Yhdessä uudelleenlajitteluerässä käsiteltävien tulosten määrä.", "OAuth": "OAuth", "OAuth / OIDC": "", "OAuth 2.1": "OAuth 2.1", @@ -1865,15 +1890,15 @@ "October": "lokakuu", "Off": "Ei käytössä", "Okay, Let's Go!": "Okei, mennään!", - "Older messages are summarized when estimated context exceeds this token limit.": "", + "Older messages are summarized when estimated context exceeds this token limit.": "Vanhemmat viestit tiivistetään, kun arvioitu konteksti ylittää tämän token-rajan.", "OLED Dark": "OLED-tumma", "Ollama": "Ollama", "Ollama API": "Ollama API", "Ollama API settings updated": "Ollama API -asetukset päivitetty", "Ollama Cloud API Key": "Ollama Cloud API avain", - "Ollama endpoint used for embeddings.": "", + "Ollama endpoint used for embeddings.": "Ollama -päätepiste upotuksia varten.", "Ollama Version": "Ollama-versio", - "Omit": "", + "Omit": "Jätä pois", "On": "Käytössä", "Once": "Kerran", "OneDrive": "OneDrive", @@ -1885,20 +1910,21 @@ "Only alphanumeric characters and hyphens are allowed in the command string.": "Vain kirjaimet, numerot ja väliviivat ovat sallittuja komentosarjassa.", "Only can be triggered when the chat input is in focus.": "Voidaan laukaista vain, kun tekstikenttä on kohdistettuna.", "Only collections can be edited, create a new knowledge base to edit/add documents.": "Vain kokoelmia voi muokata, luo uusi tietokanta muokataksesi/lisätäksesi asiakirjoja.", - "Only install functions from sources you trust.": "", - "Only install tools from sources you trust.": "", + "Only install functions from sources you trust.": "Asenna vain toimintoja lähteistä, joihin luotat.", + "Only install tools from sources you trust.": "Asenna vain työkaluja lähteistä, joihin luotat.", "Only invited users can access": "Vain kutsutut jäsenet voivat päästä", - "Only return documents with a score greater than or equal to this value.": "", + "Only return documents with a score greater than or equal to this value.": "Palauta vain dokumentit, joiden pistemäärä on suurempi tai yhtä suuri kuin tämä arvo.", "Only select users and groups with permission can access": "Vain valitut käyttäjät ja ryhmät, joilla on käyttöoikeus, pääsevät käyttämään", "Only sync new/updated chats": "Synkronoi vain uudet/päivitetyt keskustelut", - "Only when away": "", + "Only when away": "Vain kun poissa", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Hups! Näyttää siltä, että verkko-osoite on virheellinen. Tarkista se ja yritä uudelleen.", "Oops! There are files still uploading. Please wait for the upload to complete.": "Hups! Tiedostoja on vielä ladattavana. Odota, että lataus on valmis.", "Oops! There was an error in the previous response.": "Hups! Edellisessä vastauksessa oli virhe.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hups! Käytät ei-tuettua menetelmää (vain frontend). Palvele WebUI:ta backendistä.", - "Open automation": "", - "Open create menu": "", - "Open detail blocks by default.": "", + "Open": "", + "Open automation": "Avaa automaatio", + "Open create menu": "Avaa luonti-valikko", + "Open detail blocks by default.": "Avaa yksityiskohtalohkot oletuksena.", "Open file": "Avaa tiedosto", "Open in full screen": "Avaa koko näytön tilaan", "Open in new tab": "Avaa uusi välilehti", @@ -1907,13 +1933,13 @@ "Open Modal To Manage Floating Quick Actions": "Avaa modaali kelluvien pikatoimintojen hallitsemiseksi", "Open Modal To Manage Image Compression": "Avaa kuvien pakkaus hallinta modaali", "Open Model Selector": "Avaa mallinvalitsin", - "Open note": "", + "Open note": "Avaa muistiinpano", "Open Settings": "Avaa asetukset", "Open Sidebar": "Avaa sivupalkki", "Open Terminal": "Open Terminal", - "Open the changelog modal after sign-in when enabled.": "", - "Open the file browser after selecting a terminal.": "", - "Open the file manager for uploaded files.": "", + "Open the changelog modal after sign-in when enabled.": "Avaa muutosloki-ikkuna kirjautumisen jälkeen, kun se on käytössä.", + "Open the file browser after selecting a terminal.": "Avaa tiedostoselain valittuasi terminaalin.", + "Open the file manager for uploaded files.": "Avaa ladattujen tiedostojen tiedostonhallinta.", "Open User Profile Menu": "Avaa käyttäjäprofiili ikkuna", "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI voi käyttää minkä tahansa OpenAPI-palvelimen tarjoamia työkaluja.", "Open WebUI uses faster-whisper internally.": "Open WebUI käyttää faster-whisperia sisäisesti.", @@ -1925,14 +1951,14 @@ "OpenAI API Key is required.": "OpenAI API -avain vaaditaan.", "OpenAI API settings updated": "OpenAI API -asetukset päivitetty", "OpenAI URL/Key required.": "OpenAI URL/avain vaaditaan.", - "OpenAI-compatible embeddings endpoint.": "", + "OpenAI-compatible embeddings endpoint.": "OpenAI-yhteensopiva upotuspäätepiste.", "OpenAPI": "OpenAPI", "OpenAPI Spec": "OpenAPI Spec", "openapi.json URL or Path": "openapi.json verkko-osoite tai polku", "OpenID discovery URL for this provider.": "", "optional": "vaihtoehtoinen", "Optional": "Valinnainen", - "Optional API key for Ollama requests.": "", + "Optional API key for Ollama requests.": "Valinnainen API-avain Ollama-pyyntöjä varten.", "or": "tai", "Ordered List": "Järjestetty lista", "Other": "Muu", @@ -1949,7 +1975,7 @@ "PaddleOCR-vl service endpoint.": "", "page": "sivu", "Page": "Sivu", - "Page mode creates one document per page. Single mode keeps pages together for chunking across boundaries.": "", + "Page mode creates one document per page. Single mode keeps pages together for chunking across boundaries.": "Sivutila luo yhden asiakirjan per sivu. Yksittäistila pitää sivut yhdessä, jolloin pilkkominen voi ulottua sivurajojen yli.", "Paginate": "Sivutus", "Parameters": "Parametrit", "Parent message not found": "Ylätason viestiä ei löytynyt", @@ -1960,7 +1986,7 @@ "Passwords do not match.": "Salasanat eivät täsmää", "Paste inserted prompts as rich text when possible.": "", "Paste Large Text as File": "Liitä suuri teksti tiedostona", - "Path": "", + "Path": "Polku", "Path copied": "Polku kopioitu", "Paused": "Keskeytetty", "PDF document (.pdf)": "PDF-asiakirja (.pdf)", @@ -1970,10 +1996,11 @@ "Peak tokens": "", "pending": "odottaa", "Pending": "Odottaa", - "Pending Accounts": "", + "Pending Accounts": "Odottavat tilit", "Pending User Overlay Content": "Odottavien käyttäjien sisältö", "Pending User Overlay Title": "Odottavien käyttäjien otsikko", - "Permanently delete every chat after confirmation.": "", + "Percentage of recent messages to keep after older messages are summarized.": "", + "Permanently delete every chat after confirmation.": "Poista pysyvästi jokainen keskustelu vahvistuksen jälkeen.", "Permission denied when accessing media devices": "Käyttöoikeus evätty media-laitteille", "Permission denied when accessing microphone": "Käyttöoikeus evätty mikrofonille", "Permission denied when accessing microphone: {{error}}": "Käyttöoikeus evätty mikrofonille: {{error}}", @@ -1984,7 +2011,7 @@ "Perplexity Search API URL": "Perplexity Search API verkko-osoite", "Perplexity Search Context Usage": "Perplexity Search kontekstin käyttö", "Persistent": "Pysyvä", - "Personal": "", + "Personal": "Henkilökohtainen", "Personalization": "Personointi", "Picture Claim": "", "Pin": "Kiinnitä", @@ -1999,10 +2026,10 @@ "Pipelines": "Putkistot", "Pipelines are a plugin system with arbitrary code execution.": "", "Pipelines Not Detected": "Putkistoja ei havaittu", - "Place selected suggestion text into the composer.": "", + "Place selected suggestion text into the composer.": "Aseta valitut jatkokysymykset suoraan syötteeseen.", "Plain text (.md)": "Pelkkä teksti (.md)", "Plain text (.txt)": "Pelkkä teksti (.txt)", - "Play assistant responses aloud automatically.": "", + "Play assistant responses aloud automatically.": "Toista avustajan vastaukset ääneen automaattisesti.", "Playground": "Leikkipaikka", "Playwright Timeout (ms)": "Playwright aikakatkaisu (ms)", "Playwright WebSocket URL": "Playwright WebSocket verkko-osoite", @@ -2025,25 +2052,29 @@ "Please select a valid JSON file": "Valitse kelvollinen JSON-tiedosto", "Please select at least one user for Direct Message channel.": "Valitse vähintään yksi käyttäjä suoraviestikanavalle.", "Please wait until all files are uploaded.": "Odota kunnes kaikki tiedostot ovat ladattu.", - "Policy changes apply to newly provisioned terminals. Refresh matching terminals to apply them to existing terminals.": "", + "Policy changes apply to newly provisioned terminals. Refresh matching terminals to apply them to existing terminals.": "Käytäntömuutokset koskevat juuri provisionoituja terminaaleja. Päivitä vastaavat terminaalit, jotta muutokset tulevat voimaan olemassa oleviin terminaaleihin.", "Policy ID": "Käytännön ID", "Policy ID is required": "", - "Policy is still loading": "", + "Policy is still loading": "Käytäntöä ladataan edelleen", "Port": "Portti", "Ports": "Portit", "Positive attitude": "Positiivinen asenne", "Prefer not to say": "En halua sanoa", - "Preferred transcript language codes, separated by commas.": "", + "Preferred transcript language codes, separated by commas.": "Suositellut transkriptin kielikoodit, eroteltuna pilkuilla.", "Prefix ID": "Etuliite-ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Etuliite-ID:tä käytetään välttämään ristiriidat muiden yhteyksien kanssa lisäämällä etuliite mallitunnuksiin - jätä tyhjäksi, jos haluat ottaa sen pois käytöstä", - "Press keys...": "", + "Preparing download...": "", + "Press keys...": "Paina näppäimiä...", "Prevent File Creation": "Estä tiedostojen luonti", "Preview": "Esikatselu", "Preview Access": "Esikatsele käyttöoikeuksia", "Previous 30 days": "Edelliset 30 päivää", "Previous 7 days": "Edelliset 7 päivää", "Previous message": "Edellinen viesti", - "Previous page": "", + "Previous month": "", + "Previous page": "Edellinen sivu", + "Previous slide": "", + "Previous version": "", "Private": "Yksityinen", "Private conversation between selected users": "Yksityinen keskustelu käyttäjien välillä", "Production version updated": "Tuotantoversio päivitetty", @@ -2052,11 +2083,11 @@ "Prompt Autocompletion": "Kehotteen automaattinen täydennys", "Prompt Content": "Kehotteen sisältö", "Prompt created successfully": "Kehote luotu onnistuneesti", - "Prompt Menu": "", + "Prompt Menu": "Kehotevalikko", "Prompt Name": "Kehoteen nimi", "Prompt Suggestions": "Kehotusehdotukset", "Prompt Template": "Kehotepohja", - "Prompt template used when retrieved context is injected.": "", + "Prompt template used when retrieved context is injected.": "Kehotepohja, jota käytetään, kun noudettu konteksti lisätään.", "Prompt updated successfully": "Kehote päivitetty onnistuneesti", "Prompts": "Kehotteet", "Prompts Access": "Kehotteiden käyttöoikeudet", @@ -2069,9 +2100,9 @@ "Provider roles allowed to sign in.": "", "Provider roles that grant admin access.": "", "Provider URL": "", - "Provider used to generate document embeddings.": "", - "Provider used to rerank hybrid search results.": "", - "Proxy URL used for Youtube loader requests.": "", + "Provider used to generate document embeddings.": "Palveluntarjoaja, jota käytetään asiakirja-upotusten luomiseen.", + "Provider used to rerank hybrid search results.": "Palveluntarjoaja, jota käytetään hybridihakutulosten uudelleenjärjestämiseen.", + "Proxy URL used for Youtube loader requests.": "Youtube-lataajan pyyntöjä varten käytettävä välityspalvelimen URL.", "Public": "Julkinen", "Pull \"{{searchValue}}\" from Ollama.com": "Lataa \"{{searchValue}}\" Ollama.comista", "Pull a model from Ollama.com": "Lataa malli Ollama.comista", @@ -2079,7 +2110,7 @@ "Pyodide file browser": "Pyodide tiedostoselain", "Query Generation Prompt": "Kyselytulosten luontikehote", "Querying": "Kysely", - "Queue outgoing messages instead of interrupting active responses.": "", + "Queue outgoing messages instead of interrupting active responses.": "Lisää jonoon lähtevät viestit sen sijaan, että keskeytettäisiin aktiivisia vastauksia.", "Quick Actions": "Pikatoiminnot", "RAG Template": "RAG-kehote", "Ran {{COUNT}} analyses": "Suoritettiin {{COUNT}} analyysiä", @@ -2089,34 +2120,34 @@ "Read": "Lue", "Read Aloud": "Lue ääneen", "Read more →": "Lue lisää →", - "Read only": "", + "Read only": "Vain luku", "Read Only": "Vain luku", - "Read the docs": "", + "Read the docs": "Lue dokumentaatio", "Read-Only Access": "Vain lukuoikeus", "Reason": "Päättely", "Reasoning Effort": "Päättelyn määrä", "Reasoning Tags": "Päättely tagit", "Reasoning text...": "Päättely teksti...", - "Rebuild vectors for existing knowledge files.": "", - "Receives matching events across the instance, including system/config events and events associated with any user.": "", - "Receives matching events that are not associated with a user.": "", - "Receives matching user-associated events only when the actor, user subject, or user data matches these users or current group members. System/config events are not sent.": "", + "Rebuild vectors for existing knowledge files.": "Tee olemassa olevien tietämystiedostojen vektorit uudelleen.", + "Receives matching events across the instance, including system/config events and events associated with any user.": "Vastaanottaa koko instanssissa vastaavia tapahtumia, mukaan lukien järjestelmä- ja konfiguraatiotapahtumat sekä kenen tahansa käyttäjän tapahtumat.", + "Receives matching events that are not associated with a user.": "Vastaanottaa vastaavia tapahtumia, joita ei ole liitetty käyttäjään.", + "Receives matching user-associated events only when the actor, user subject, or user data matches these users or current group members. System/config events are not sent.": "Vastaanottaa vastaavia käyttäjään liittyviä tapahtumia vain silloin, kun toimija, kohdekäyttäjä tai käyttäjätiedot vastaavat näitä käyttäjiä tai nykyisen ryhmän jäseniä. Järjestelmä- ja konfiguraatiotapahtumia ei lähetetä.", "Recently Used": "Viimeeksi käytetty", "Reconnected": "Yhdistetty", "Record": "Nauhoita", "Record voice": "Nauhoita ääntä", - "Redirect URI": "", + "Redirect URI": "Uudelleenohjaus URI", "Redirecting you to Open WebUI Community": "Ohjataan sinut OpenWebUI-yhteisöön", "Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "Vähentää hölynpölyn tuottamisen todennäköisyyttä. Korkeampi arvo (esim. 100) antaa monipuolisempia vastauksia, kun taas matalampi arvo (esim. 10) on varovaisempi.", "Reference Chats": "Liitä keskustelu", "Refresh": "Päivitä", "Refresh requested: {{count}} terminal(s)_one": "", "Refresh requested: {{count}} terminal(s)_other": "", - "Refresh Terminals": "", - "Refresh the account email from OAuth on sign-in.": "", - "Refresh the account name from OAuth on sign-in.": "", - "Refresh the profile picture from OAuth on sign-in.": "", - "Refreshing...": "", + "Refresh Terminals": "Päivitä päätteet", + "Refresh the account email from OAuth on sign-in.": "Päivitä tilin sähköpostiosoite OAuthista kirjautumisen yhteydessä.", + "Refresh the account name from OAuth on sign-in.": "Päivitä tilin nimi OAuthista kirjautumisen yhteydessä.", + "Refresh the profile picture from OAuth on sign-in.": "Päivitä tilin profiilikuva OAuthista kirjautumisen yhteydessä.", + "Refreshing...": "Päivitetään...", "Refused when it shouldn't have": "Kieltäytyi, vaikka ei olisi pitänyt", "Regenerate": "Regeneroi", "Regenerate Menu": "Regenerointi ikkuna", @@ -2137,14 +2168,14 @@ "Remove": "Poista", "Remove {{MODELID}} from list.": "Poista {{MODELID}} listalta", "Remove action": "Poista toiminto", - "Remove existing OCR text and rerun OCR when Force OCR is off.": "", + "Remove existing OCR text and rerun OCR when Force OCR is off.": "Poista olemassa oleva OCR-teksti ja suorita OCR uudelleen, kun Force OCR -asetus on pois käytöstä.", "Remove file": "Poista tiedosto", "Remove File": "Poista tiedosto", "Remove from favorites": "Poista suosikeista", "Remove image": "Poista kuva", - "Remove Pinned Model": "", - "Remove prompt suggestion": "", - "Remove Selected Model": "", + "Remove Pinned Model": "Poista kiinnitetty malli", + "Remove prompt suggestion": "Poista kehotusehdotus", + "Remove Selected Model": "Poista valittu malli", "Removing {{count}} stale files..._one": "Poistetaan {{count}} vanhentunutta tiedostoa..._one", "Removing {{count}} stale files..._other": "Poistetaan {{count}} vanhentuneita tiedostoja..._other", "Rename": "Nimeä uudelleen", @@ -2152,14 +2183,14 @@ "Render Markdown in Assistant Messages": "Renderöi Markdown avustajan viesteissä", "Render Markdown in Previews": "Renderöi Markdown esikatseluissa", "Render Markdown in User Messages": "Renderöi Markdown käyttäjän viesteissä", - "Render messages in compact bubble containers.": "", - "Repeat": "", + "Render messages in compact bubble containers.": "Renderöi viestit kompakteissa kuplakonteissa.", + "Repeat": "Toista", "Reply": "Vastaa", "Reply in Thread": "Vastaa ketjussa", "Reply to thread...": "Vastaa ketjussa...", "Replying to {{NAME}}": "Vastaa {{NAME}}", "Request Format": "", - "Require users to confirm before using Web Search.": "", + "Require users to confirm before using Web Search.": "Vaadi käyttäjiä vahvistamaan ennen verkkohaun käyttöä.", "required": "vaaditaan", "Reranking Batch Size": "Uudelleenpisteytyksen eräkoko", "Reranking Engine": "Uudelleenpisteytymismallin moottori", @@ -2167,54 +2198,56 @@ "Research Knowledge": "", "Reset": "Palauta", "Reset All Models": "Palauta kaikki mallit", - "Reset all permissions to their initial configuration values": "", - "Reset Defaults": "", - "Reset group permissions to match the current default user permissions": "", + "Reset all permissions to their initial configuration values": "Palauta kaikki oikeudet niiden alkuperäisiin määritysarvoihin.", + "Reset Defaults": "Palauta oletukset", + "Reset group permissions to match the current default user permissions": "Palauta ryhmän oikeudet vastaamaan nykyisiä oletuskäyttäjäoikeuksia", "Reset knowledge base?": "Nollataanko tietokanta?", - "Reset persisted files": "", - "Reset to Defaults": "", + "Reset persisted files": "Nollaa pysyvät tiedostot", + "Reset to Defaults": "Palauta oletuksiin", "Reset Upload Directory": "Palauta latauspolku", "Reset Vector Storage/Knowledge": "Tyhjennä vektoritallennukset/tietämys", "Reset view": "Palauta näkymä", "Response": "Vastaus", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Vastausilmoituksia ei voida ottaa käyttöön, koska verkkosivuston käyttöoikeudet on evätty. Myönnä tarvittavat käyttöoikeudet selaimesi asetuksista.", - "Response Splitting": "", + "Response Splitting": "Vastauksen katkaisu", "Response Watermark": "Vastauksen vesileima", "Responses": "", "Restart": "Käynnistä uudelleen", - "Restrict or exclude domains using a comma-separated list.": "", + "Restrict or exclude domains using a comma-separated list.": "Rajoita tai poissulje verkkotunnuksia pilkulla erotellulla luettelolla.", "Result": "Tulos", "RESULT": "Tulos", + "Retained Messages": "", "Retrieval": "Haku", "Retrieval Query Generation": "Hakukyselyn luominen", "Retrieved {{count}} sources": "Noudettu {{count}} lähdettä", "Retrieved {{count}} sources_one": "Noudettu {{count}} sources_one", "Retrieved {{count}} sources_other": "Noudettu {{count}} sources_other", "Retrieved 1 source": "1 lähde noudettu", - "Retry": "", - "Review and manage chats you have shared.": "", - "Rewrite the selected text.": "", - "Rewrite user requests for knowledge retrieval.": "", - "Rewrite user requests into web-search queries.": "", - "Rewrites user intent into an image-generation prompt.": "", + "Retry": "Yritä uudelleen", + "Review and manage chats you have shared.": "Tarkastele ja hallinnoi jakamiasi keskusteluja.", + "Rewrite the selected text.": "Kirjoita valittu teksti uudelleen.", + "Rewrite user requests for knowledge retrieval.": "Kirjoita käyttäjäpyynnöt uudelleen tiedonhakua varten.", + "Rewrite user requests into web-search queries.": "Kirjoita käyttäjäpyynnöt uudelleen verkkohakukyselyiksi.", + "Rewrites user intent into an image-generation prompt.": "Muotoilee käyttäjän aikomuksen kuvan generoinnin kehotteeksi.", "Rich Text Input for Chat": "Rikasteksti-kenttä chattiin", "Role": "Rooli", - "Role assigned to new users when they create an account.": "", + "Role assigned to new users when they create an account.": "Rooli, joka annetaan uusille käyttäjille tilin luomisen yhteydessä.", "Role Mapping": "", "Roles Claim": "", "RTL": "RTL", "Run": "Suorita", - "Run AI on your own terms. Connect any model, extend with code, and protect what matters without compromise. Your models, your data, your machine, wherever you open it.": "", + "Run AI on your own terms. Connect any model, extend with code, and protect what matters without compromise. Your models, your data, your machine, wherever you open it.": "Käytä tekoälyä omilla ehdoillasi. Yhdistä mikä tahansa malli, laajenna koodilla ja suojaa se, mikä on tärkeää, ilman kompromisseja. Mallisi, tietosi, koneesi — missä tahansa avaat sen.", "Run All": "Suorita kaikki", - "Run embedding tasks concurrently to speed up processing.": "", + "Run embedding tasks concurrently to speed up processing.": "Suorita upotustehtävät samanaikaisesti käsittelyn nopeuttamiseksi.", "Run now": "Suorita nyt", "Run Now": "Suorita nyt", - "Run OCR on all PDF pages, even pages with embedded text.": "", + "Run OCR on all PDF pages, even pages with embedded text.": "Suorita OCR kaikilla PDF-sivuilla, myös sivuilla, joilla on upotettua tekstiä.", "Running": "Käynnissä", "Running Open WebUI for a team?": "", "Running...": "Käynnissä...", - "runs": "", - "Runs": "", + "runs": "suoritukset", + "Runs": "Suoritukset", "Sa_day_of_week": "", "Save": "Tallenna", "Save & Create": "Tallenna ja luo", @@ -2222,18 +2255,19 @@ "Save As Copy": "Tallenna kopiona", "Save Chat": "Tallenna keskustelu", "Saved": "Tallennettu", - "Saved Memories": "", + "Saved Memories": "Tallennetut muistot", "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Keskustelulokien tallentaminen suoraan selaimen tallennustilaan ei ole enää tuettu. Lataa ja poista keskustelulokit napsauttamalla alla olevaa painiketta. Älä huoli, voit helposti tuoda keskustelulokit takaisin backendiin", - "Saving...": "", + "Saving...": "Tallenetaan...", "Schedule": "Aikataulu", "Scheduled time must be in the future": "Aikataulutetun ajan on oltava tulevaisuudessa", "Scopes": "", "Scroll On Branch Change": "Vieritä haaran vaihtoon", - "Scroll to the active branch when switching response branches.": "", + "Scroll to bottom": "", + "Scroll to the active branch when switching response branches.": "Vieritä aktiiviseen haaraan vaihtaessasi vastaushaaroja.", "Scroll to Top": "Vieritä ylös", "Search": "Haku", "Search a model": "Hae mallia", - "Search actions": "", + "Search actions": "Hae toimitoja", "Search all emojis": "Hae emojeista", "Search and manage user memories": "Hae ja hallinnoi käyttäjien muistoja", "Search and view user chat history": "Hae ja tarkastele käyttäjän keskusteluhistoriaa", @@ -2243,8 +2277,9 @@ "Search Chats": "Hae keskusteluja", "Search Collection": "Hae kokoelmaa", "Search Files": "Hae tiedostoja", - "Search filters": "", + "Search filters": "Hae suodattimia", "Search Filters": "Hakusuodattimet", + "Search folders": "", "search for archived chats": "Hae arkistoiduista keskusteluista", "search for folders": "Hae kansioista", "search for pinned chats": "Hae kiinnitetyistä keskusteluista", @@ -2254,7 +2289,7 @@ "Search Groups": "Etsi ryhmiä", "Search In Models": "Hae mallleista", "Search Knowledge": "Hae tietämystä", - "Search Limits": "", + "Search Limits": "Hakurajoitukset", "Search Memories": "Hae muistoista", "Search Models": "Hae malleja", "Search Notes": "Hae muistiinpanoista", @@ -2262,13 +2297,13 @@ "Search or add pattern": "", "Search Prompts": "Hae kehotteita", "Search Result Count": "Hakutulosten määrä", - "Search skills": "", + "Search skills": "Hae taitoja", "Search Skills": "Etsi taitoja", "Search the internet": "Hae verkosta", "Search the web and fetch URLs": "Hae verkosta ja hae URL-osoitteita", - "Search tools": "", + "Search tools": "Hae työkaluja", "Search Tools": "Hae työkaluja", - "Search users or groups": "", + "Search users or groups": "Hae käyttäjiä tai ryhmiä", "Search, view, and manage user notes": "Hae, tarkastele ja hallinnoi käyttäjämuistiinpanoja", "SearchApi API Key": "SearchApi API -avain", "SearchApi Engine": "SearchApi-moottori", @@ -2279,13 +2314,13 @@ "Searching the web": "Haetaan verkosta...", "Searxng Query URL": "Searxng-kyselyn verkko-osoite", "Searxng search language (all, en, es, de, fr, etc.)": "Hakukieli (all, en, es, de, fr jne.)", - "Secrets": "", + "Secrets": "Salaisuudet", "See readme.md for instructions": "Katso ohjeet readme.md-tiedostosta", "See what's new": "Katso, mitä uutta", "Seed": "Siemenluku", "Select": "Valitse", "Select {{modelName}} model": "Valitse {{modelName}} malli", - "Select a .py file": "", + "Select a .py file": "Valitse .py tiedosto", "Select a base model (e.g. llama3, gpt-4o)": "Valitse perusmalli (esim. llama3, gtp-4o)", "Select a conversation to preview": "Valitse keskustelun esikatselu", "Select a engine": "Valitse moottori", @@ -2302,7 +2337,7 @@ "Select a theme": "Valitse teema", "Select a tool": "Valitse työkalu", "Select a voice": "Valitse ääni", - "Select Action": "", + "Select Action": "Valitse toiminto", "Select All": "Valitse kaikki", "Select an auth method": "Valitse kirjautumistapa", "Select an embedding model engine": "Valitse upotusmallin moottori", @@ -2313,69 +2348,70 @@ "Select an output format": "Valitse tulostusmuoto", "Select dtype": "Valitse dtype", "Select Engine": "Valitse moottori", - "Select Filter": "", - "Select how audio is sent to the OpenAI-compatible endpoint.": "", - "Select how Open WebUI authenticates with the Jupyter server.": "", + "Select Filter": "Valitse suodatin", + "Select how audio is sent to the OpenAI-compatible endpoint.": "Valitse miten ääni lähetetään OpenAI-yhteensopivalle päätepisteelle.", + "Select how Open WebUI authenticates with the Jupyter server.": "Valitse, miten Open WebUI todentaa itsensä Jupyter-palvelimeen.", "Select how to split message text for TTS requests": "Valitse, miten viestit jaetaan TTS-pyyntöjä varten", "Select Knowledge": "Valitse tietämys", "Select Method": "Valitse metodi", "Select model": "Valitse malli", "Select only one model to call": "Valitse vain yksi malli kutsuttavaksi", - "Select Skill": "", + "Select Skill": "Valitse taito", "Select the Gemini endpoint method to call.": "", "Select the local model precision used by Kokoro.js.": "", "Select the Pipelines server to manage.": "", - "Select Tool": "", + "Select Tool": "Valitse työkalu", "Select view": "Valitse näkymä", - "Selected": "", + "Selected": "Valittu", "Selected model: {{modelName}}": "Valittu malli: {{modelName}}", "Selected model(s) do not support image inputs": "Valitut mallit eivät tue kuvasyötteitä", + "Selected models define incompatible Chat Variables.": "", "semantic": "Semaattinen", "Send": "Lähetä", "Send a Message": "Lähetä viesti", "Send events for": "", - "Send extra JSON parameters with each AUTOMATIC1111 request.": "", - "Send extra JSON parameters with each image generation request.": "", + "Send extra JSON parameters with each AUTOMATIC1111 request.": "Lähetä lisäparametrit JSON muodossa jokaisen AUTOMATIC1111-pyynnön mukana.", + "Send extra JSON parameters with each image generation request.": "Lähetä lisäparametrit JSON muodossa jokaisen kuvan generointipyynnön mukana.", "Send message": "Lähetä viesti", - "Send notifications to configured webhook targets": "", + "Send notifications to configured webhook targets": "Lähetä ilmoituksia määritetyille webhookkeille.", "Send now": "Lähetä nyt", "Send PDFs as base64 data URLs instead of uploading first.": "", "Send product events as JSON to external services. Chat destinations receive readable messages.": "", - "Send Test": "", - "Send transcribed voice input immediately after speech recognition finishes.": "", + "Send Test": "Lähetä testi", + "Send transcribed voice input immediately after speech recognition finishes.": "Lähetä litteroitu tuloääni heti puheentunnistuksen päätyttyä.", "Send users directly to the OAuth provider from the sign-in page.": "", "Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "Lähettää `stream_options: { include_usage: true }` pyynnössä.\nTuetut tarjoajat palauttavat tokenkäyttötiedot vastauksessa, kun se on asetettu.", - "Separate output by page with page markers.": "", + "Separate output by page with page markers.": "Erottele tuloste sivuittain sivumerkkien avulla.", "September": "syyskuu", "SerpApi API Key": "SerpApi API -avain", "SerpApi Engine": "SerpApi moottori", "Serper API Key": "Serper API -avain", - "SERPHouse API Key": "", - "SERPHouse Domain": "", + "SERPHouse API Key": "SERPHouse API -avain", + "SERPHouse Domain": "SERPHouse-verkkotunnus", "Serply API Key": "Serply API -avain", "Serpstack API Key": "Serpstack API -avain", "Server connection failed": "Palvelinyhteys epäonnistui", "Server connection verified": "Palvelinyhteys vahvistettu", "Service Account": "", "Session": "Istunto", - "Session expired. Please sign in again.": "", - "Set a local zoom level for the app interface.": "", - "Set a model-specific context compaction token threshold. When set, this overrides the global threshold up to the global cap.": "", - "Set a speech recognition language or leave it blank to detect automatically.": "", + "Session expired. Please sign in again.": "Istunto on vanhentunut. Kirjaudu uudelleen.", + "Set a local zoom level for the app interface.": "Aseta paikallinen zoomaustaso sovelluksen käyttöliittymälle.", + "Set a model-specific context compaction token threshold. When set, this overrides the global threshold up to the global cap.": "Aseta mallikohtainen kontekstin tiivistyksen token-kynnys. Kun se on asetettu, se ohittaa globaalin kynnyksen globaalin katon rajoihin saakka.", + "Set a speech recognition language or leave it blank to detect automatically.": "Aseta puheentunnistuksen kieli tai jätä tyhjäksi automaattista tunnistusta varten.", "Set as default": "Aseta oletukseksi", - "Set as Pinned Model": "", + "Set as Pinned Model": "Aseta kiinitetty malli", "Set as Production": "Aseta tuotantokäyttöön", - "Set as Selected Model": "", + "Set as Selected Model": "Aseta valittu malli", "Set embedding model": "Aseta upotelmamalli", "Set embedding model (e.g. {{model}})": "Aseta upotelmamalli (esim. {{model}})", "Set reranking model (e.g. {{model}})": "Aseta uudelleenpisteytymismalli (esim. {{model}})", - "Set the birth date saved with your profile.": "", - "Set the default system prompt for new chats.": "", - "Set the display name shown across your account.": "", + "Set the birth date saved with your profile.": "Aseta profiiliisi tallennettu syntymäaika.", + "Set the default system prompt for new chats.": "Aseta oletusjärjestelmäkehote uusille keskusteluille.", + "Set the display name shown across your account.": "Aseta tililläsi näkyvä näyttönimi.", "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "Aseta näytönohjaimelle ladattavien tasojen määrä. Tämän arvon kasvattaminen voi parantaa merkittävästi näytönohjaimelle optimoitujen mallien suorituskykyä, mutta se voi myös lisätä näytönohjaimen virrankulutusta ja resurssien käyttöä.", "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Aseta työntekijäsäikeiden määrä laskentaa varten. Tämä asetus kontrolloi, kuinka monta säiettä käytetään saapuvien pyyntöjen rinnakkaiseen käsittelyyn. Arvon kasvattaminen voi parantaa suorituskykyä suurissa samanaikaisissa työkuormissa, mutta voi myös kuluttaa enemmän keskussuorittimen resursseja.", "Set Voice": "Aseta puheääni", - "Set web search availability for new chats.": "", + "Set web search availability for new chats.": "Aseta verkkohakujen saatavuus uusille keskusteluille.", "Set whisper model": "Aseta whisper-malli", "Set your status": "Aseta tilasi", "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "Asettaa tasaisen vinouman niitä tokeneita kohtaan, jotka ovat esiintyneet vähintään kerran. Korkeampi arvo (esim. 1.5) rankaisee toistoja voimakkaammin, kun taas matalampi arvo (esim. 0.9) on lievempi. Arvolla 0 se on pois päältä.", @@ -2394,35 +2430,35 @@ "Share link copied to clipboard.": "Jakolinkki kopioitu leikepöydälle.", "Share to Open WebUI Community": "Jaa OpenWebUI-yhteisöön", "Share your background and interests": "Jaa taustasi ja kiinnostuksen kohteesi", - "Share your current location with features that can use it.": "", - "Shared": "", + "Share your current location with features that can use it.": "Jaa nykyinen sijaintisi ominaisuuksille, jotka voivat käyttää sitä.", + "Shared": "Jaettu", "Shared Chats": "Jaetut keskustelut", - "Shared prompt for retrieval and web-search query rewriting.": "", + "Shared prompt for retrieval and web-search query rewriting.": "Jaettu kehote hakua ja verkkohakukyselyiden uudelleenkirjoittamista varten.", "Shared with you": "Jaettu kanssasi", "Sharing Permissions": "Jako oikeudet", "Show": "Näytä", "Show \"What's New\" Modal on Login": "Näytä \"Mitä uutta\" -modaali kirjautumisen yhteydessä", - "Show admin contact details while an account waits for approval.": "", + "Show admin contact details while an account waits for approval.": "Ylläpidon yhteystiedot, jotka näytetään tilin odottaessa hyväksyntää.", "Show All": "Näytä kaikki", "Show all ({{COUNT}} characters)": "Näytä kaikki ({{COUNT}} merkkiä)", - "Show emoji feedback in the call interface.": "", + "Show emoji feedback in the call interface.": "Näytä hymiöpalautteita puhelun käyttöliittymässä.", "Show Files": "Näytä tiedostot", "Show Files on Terminal Select": "", "Show formatting controls in the rich text composer.": "", "Show Formatting Toolbar": "Näytä muotoilupalkki", "Show image preview": "Näytä kuvan esikatselu", "Show Model": "Näytä malli", - "Show more": "", - "Show or hide custom generation parameters.": "", - "Show or hide sensitive account secrets.": "", + "Show more": "Näytä lisää", + "Show or hide custom generation parameters.": "Näytä tai piilota mukautetut generointiparametrit.", + "Show or hide sensitive account secrets.": "Näytä tai piilota tilin arkaluonteiset tiedot.", "Show Shortcuts": "Näytä pikakomennot", - "Show suggested next questions after assistant responses.": "", - "Show the floating quick-action toolbar in chat.": "", - "Show the regenerate action menu for assistant responses.": "", - "Show update toasts to admins when new versions are available.": "", - "Show user status information in the app.": "", + "Show suggested next questions after assistant responses.": "Näytä avustajan vastausten jälkeen ehdotetut kysymykset.", + "Show the floating quick-action toolbar in chat.": "Näytä kelluva pikatoimintopalkki keskustelussa.", + "Show the regenerate action menu for assistant responses.": "Näytä uudelleen regeneroinnin toimintovalikko avustajan vastauksille.", + "Show update toasts to admins when new versions are available.": "Näytä päivitysilmoitukset ylläpitäjille, kun uusia versioita on saatavilla.", + "Show user status information in the app.": "Näytä käyttäjän tilatiedot sovelluksessa", "Show your support!": "Osoita tukesi!", - "Show your username label instead of You in chat bubbles.": "", + "Show your username label instead of You in chat bubbles.": "Näytä käyttäjänimi keskustelukuplissa \"Sinä\" -tekstin sijaan", "Showcased creativity": "Osoitti luovuutta", "Showing all messages (user + assistant) per user.": "Näytetään kaikki viestit (käyttäjä + avustaja) käyttäjää kohden.", "Sign in": "Kirjaudu sisään", @@ -2432,7 +2468,7 @@ "Sign up": "Rekisteröidy", "Sign up to {{WEBUI_NAME}}": "Rekisteröidy palveluun {{WEBUI_NAME}}", "Signing in to {{WEBUI_NAME}}": "Kirjaudutaan sisään palveluun {{WEBUI_NAME}}", - "simultaneous sub-agents": "", + "simultaneous sub-agents": "Samanaikaiset aliagentit", "Single": "", "Sink List": "Upotuslista", "sk-1234": "sk-1234", @@ -2442,7 +2478,7 @@ "Skill ID": "Taidon ID", "Skill imported successfully": "Taito tuotiin onnistuneesti", "Skill Instructions": "Taidon ohjeistus", - "Skill Menu": "", + "Skill Menu": "Taitovalikko", "Skill Name": "Taidon nimi", "Skill updated successfully": "Taito päivitetty onnistuneesti", "Skills": "Taidot", @@ -2450,7 +2486,8 @@ "Skills Public Sharing": "Taitojen julkinen jakaminen", "Skills Sharing": "Taitojen jako", "Skip Cache": "Ohita välimuisti", - "Skip cached Marker results and rerun inference.": "", + "Skip to main content": "", + "Skip cached Marker results and rerun inference.": "Ohita välimuistiin tallennetut Marker-tulokset ja suorita uudelleen.", "Something went wrong :/": "Jokin meni pieleen :/", "Sonar": "Sonar", "Sonar Deep Research": "Sonar Deep Research", @@ -2461,16 +2498,16 @@ "Sougou Search API sID": "Sougou Search API sID", "Sougou Search API SK": "Sougou Search API SK", "Source": "Lähde", - "Specific users or groups": "", + "Specific users or groups": "Tietyt käyttäjät tai ryhmät", "Speech Playback Speed": "Puhetoiston nopeus", "Speech recognition error: {{error}}": "Puheentunnistusvirhe: {{error}}", "Speech-to-Text": "Puheentunnistus", "Speech-to-Text Engine": "Puheentunnistusmoottori", "Speech-to-Text Language": "Puheentunnistus kieli", - "Split documents by markdown headers before character or token splitting.": "", - "Sponsor on GitHub": "", + "Split documents by markdown headers before character or token splitting.": "Jaa asiakirjat Markdown-otsikoiden mukaan ennen merkkien tai tokenien pilkkomista.", + "Sponsor on GitHub": "Sponsoroi GitHubissa", "Start a new conversation": "Aloita uusi keskustelu", - "Start new chats as temporary unless changed.": "", + "Start new chats as temporary unless changed.": "Aloita uudet keskustelut väliaikaisina, ellei niitä muuteta.", "Start of the channel": "Kanavan alku", "Start Tag": "Aloitus tagi", "Starting in {{count}} minutes_one": "Aloitetaan {{count}} minutes_one", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Askeleet", "Stop": "Pysäytä", + "Stop camera": "", "Stop Download": "Lopeta lataus", "Stop Generating": "Lopeta generointi", "Stop Sequence": "Lopetussekvenssi", @@ -2499,7 +2537,7 @@ "Stylized PDF Export": "Muotoiltun PDF-vienti", "Su_day_of_week": "", "Sub Claim": "", - "Sub-agents": "", + "Sub-agents": "Aliagentit", "Submit question": "Lähetä kysymys", "Submit suggestion": "Lähetä ehdotus", "Subtitle": "Alaotsikko", @@ -2507,15 +2545,16 @@ "Successfully imported {{userCount}} users.": "{{userCount}} käyttäjää tuottiin onnistuneesti.", "Successfully updated.": "Päivitetty onnistuneesti.", "Suggest a change": "Ehdota muutosta", - "Suggest completions while composing prompts.": "", - "Suggest completions while users type chat messages.": "", + "Suggest completions while composing prompts.": "Ehdota täydennyksiä rituksia samalla kun laadit kehotteita.", + "Suggest completions while users type chat messages.": "Ehdota täydennyksiä, kun käyttäjät kirjoittavat keskusteluviestejä.", "Suggested": "Ehdotukset", - "Suggested prompts": "", - "Summarize older chat history when the conversation context grows large.": "", - "Summarize this note.": "", + "Suggested prompts": "Ehdotetut kehotteet", + "Summarize older chat history when the conversation context grows large.": "Tiivistä vanhempaa keskusteluhistoriaa, kun keskustelun konteksti kasvaa suureksi.", + "Summarize this note.": "Tiivistä tämä muistiinpano.", "Support": "Tuki", "Support this plugin:": "Tue tätä lisäosaa:", "Supported MIME Types": "Tuetut MIME-tyypit", + "Switch camera": "", "Switch to JSON editor": "Vaihda JSON-editoriin", "Switch to visual editor": "Vaihda visuaaliseen editoriin", "Sync": "Synkronoi", @@ -2529,11 +2568,11 @@ "Syncing...": "Synkronoidaan...", "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Synkronoi vain keskustelut, joihin on tehty päivityksiä viimeisen synkronoinnin aikaleiman jälkeen. Poista käytöstä synkronoidaksesi kaikki keskustelut uudelleen.", "System": "Järjestelmä", - "System events only": "", + "System events only": "Vain järjestelmän tapahtumat", "System Instructions": "Järjestelmäohjeet", - "System prompt": "", + "System prompt": "Järjestelmäkehote", "System Prompt": "Järjestelmäkehote", - "Table": "", + "Table": "Taulukko", "Tag": "Tagi", "Tags": "Tagit", "Tags Generation": "Tagien luonti", @@ -2556,14 +2595,14 @@ "Temporary Chat by Default": "Väliaikainen keskustelu oletuksena", "Terminal": "Pääte", "Terminal servers saved": "Päätepalvelimet tallennettu", - "Test": "", - "Test must pass before a source is created.": "", - "Test notification sent.": "", - "Test Query": "", - "Test returned no results.": "", - "Test succeeded.": "", - "Test the source before creating it.": "", - "Test the source before saving it.": "", + "Test": "Testi", + "Test must pass before a source is created.": "Testi täytyy läpäistä ennen kuin lähde luodaan.", + "Test notification sent.": "Testi-ilmoitus lähetetty.", + "Test Query": "Testikysely", + "Test returned no results.": "Testi ei palauttanut tuloksia.", + "Test succeeded.": "Testi onnistui.", + "Test the source before creating it.": "Testaa lähde ennen sen luomista.", + "Test the source before saving it.": "Testaa lähde ennen tallentamista.", "Text output format returned by Marker.": "", "Text Splitter": "Tekstin jakaja", "Text-to-Speech": "Puhesynteesi", @@ -2595,7 +2634,7 @@ "This folder is empty": "Tämä kansio on tyhjä", "This is a default user permission and will remain enabled.": "Tämä on oletusarvoinen käyttäjäoikeus ja pysyy käytössä.", "This is an experimental feature, it may not function as expected and is subject to change at any time.": "Tämä on kokeellinen ominaisuus, se ei välttämättä toimi odotetulla tavalla ja se voi muuttua milloin tahansa.", - "This knowledge base retrieves from a connected source. Open WebUI can query it, but cannot upload, sync, edit, delete, reset, or reindex its source data.": "", + "This knowledge base retrieves from a connected source. Open WebUI can query it, but cannot upload, sync, edit, delete, reset, or reindex its source data.": "Tämä tietokanta hakee tietoja yhdistetystä lähteestä. Open WebUI voi tehdä siihen kyselyjä, mutta ei voi ladata, synkronoida, muokata, poistaa, nollata tai uudelleenindeksoida sen lähdetietoja.", "This model is not publicly available. Please select another model.": "Tämä malli ei ole julkisesti saatavilla. Valitse toinen malli.", "This option controls how long the model will stay loaded into memory following the request (default: 5m)": "Tämä asetus määrittää kuinka kauan malli pysyy ladattuna muistissa pyynnön jälkeen (oletusarvo: 5m)", "This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "Tämä asetus määrittää, kuinka monta tokenia säilytetään kontekstia päivitettäessä. Jos arvoksi on asetettu esimerkiksi 2, keskustelukontekstin kaksi viimeistä tokenia säilytetään. Kontekstin säilyttäminen voi auttaa ylläpitämään keskustelun jatkuvuutta, mutta se voi heikentää kykyä vastata uusiin aiheisiin.", @@ -2617,14 +2656,14 @@ "Through": "", "Thumbs up/down ratings from users on model responses": "Käyttäjien peukku-/alas-arviot mallien vastauksista", "Tika": "Tika", - "Tika server endpoint used for content extraction.": "", - "Tika Server URL": "", + "Tika server endpoint used for content extraction.": "Tika-palvelimen päätepiste sisällön poimintaa varten.", + "Tika Server URL": "Tika palvelimen verkko-osoite", "Tika Server URL required.": "Tika palvelimen verkko-osoite vaaditaan.", "Tiktoken": "Tiktoken", "Time": "Aika", "Time & Calculation": "Aika ja laskenta", "Timeout": "Aikakatkaisu", - "Timer": "", + "Timer": "Ajastin", "Title": "Otsikko", "Title Auto-Generation": "Otsikon automaattinen luonti", "Title cannot be an empty string.": "Otsikko ei voi olla tyhjä merkkijono.", @@ -2632,7 +2671,7 @@ "Title Generation Prompt": "Otsikon luontikehote", "Title is required": "Otsikko on pakollinen", "TLS": "TLS", - "TLS cipher list for LDAP connections.": "", + "TLS cipher list for LDAP connections.": "TLS-salaimien luettelo LDAP-yhteyksille.", "To access the available model names for downloading,": "Päästäksesi käsiksi ladattavissa oleviin mallinimiin,", "To access the GGUF models available for downloading,": "Päästäksesi käsiksi ladattavissa oleviin GGUF-malleihin,", "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Päästäksesi käyttämään WebUI:ta, ota yhteyttä ylläpitäjään. Ylläpitäjät voivat hallita käyttäjien tiloja Ylläpitopaneelista.", @@ -2640,11 +2679,11 @@ "To learn more about available endpoints, visit our documentation.": "Jos haluat lisätietoja käytettävissä olevista päätepisteistä, tutustu dokumentaatioomme.", "To learn more about SpeechT5,": "", "To see the available CMU Arctic speaker embeddings,": "", - "To select actions here, add them to the \"Functions\" workspace first.": "", - "To select default filters here, enable toggleable filters for this model first.": "", - "To select filters here, add them to the \"Functions\" workspace first.": "", + "To select actions here, add them to the \"Functions\" workspace first.": "Jos haluat valita toimintoja tässä, lisää ne ensin \"Toiminnot\"-työtilaan.", + "To select default filters here, enable toggleable filters for this model first.": "Jos haluat valita oletussuodattimia tässä, ota ensin käyttöön tälle mallille kytkettävät suodattimet.", + "To select filters here, add them to the \"Functions\" workspace first.": "Jos haluat valita suodattimia tässä, lisää ne ensin \"Toiminnot\"-työtilaan.", "To select skills here, add them to the \"Skills\" workspace first.": "Jos haluat valita taitoja tässä, lisää ne ensin \"Taidot\"-työtilaan.", - "To select toolkits here, add them to the \"Tools\" workspace or enable a tool server first.": "", + "To select toolkits here, add them to the \"Tools\" workspace or enable a tool server first.": "Jos haluat valita työkaluja tässä, lisää ne ensin \"Työkalut\"-työtilaan tai ota ensin käyttöön työkalupalvelin.", "Toast Notifications for New Updates": "Ilmoituspopuppien näyttäminen uusista päivityksistä", "Today": "Tänään", "Today at": "Tänään", @@ -2658,9 +2697,9 @@ "Toggle whether current connection is active.": "Vaihda, onko nykyinen yhteys aktiivinen", "Token": "Token", "Token activity": "", - "Token Cap": "", + "Token Cap": "Token-raja", "Token counts are estimates and may not reflect actual API usage": "Tokenmäärät ovat arvioita eivätkä välttämättä vastaa todellista API-käyttöä", - "Token Threshold": "", + "Token Threshold": "Tokenkynnys", "Tokenizer Model": "", "Tokenizer model used for transformer token splitting.": "", "tokens": "tokenit", @@ -2671,14 +2710,14 @@ "Tool Description": "Työkalun kuvaus", "Tool ID": "Työkalun tunnus", "Tool imported successfully": "Työkalu tuotu onnistuneesti", - "tool loops per sub-agent": "", - "Tool Menu": "", + "tool loops per sub-agent": "Työkalusilmukat aliagenttia kohden", + "Tool Menu": "Työkaluvalikko", "Tool Name": "Työkalun nimi", "Tool Servers": "Työkalu palvelin", "Tool updated successfully": "Työkalu päivitetty onnistuneesti", "Tools": "Työkalut", "Tools Access": "Työkalujen käyttöoikeudet", - "Tools can execute arbitrary code.": "", + "Tools can execute arbitrary code.": "Työkalut voivat suorittaa mielivaltaista koodia.", "Tools Function Calling Prompt": "Työkalujen kutsukehote", "Tools have a function calling system that allows arbitrary code execution.": "Työkalut sallivat mielivaltaisen koodin suorittamisen toimintokutsuilla.", "Tools Public Sharing": "Työkalujen julkinen jakaminen", @@ -2686,8 +2725,8 @@ "Top": "", "Top K": "Top K", "Top K Reranker": "Top K uudelleen sijoittaja", - "Top models": "", - "Total chats": "", + "Top models": "Käytetyimmät mallit", + "Total chats": "Keskusteluja kaikkiaan", "Transformers": "Muunnokset", "Trouble accessing Ollama?": "Ongelmia Ollama-yhteydessä?", "Trust Proxy Environment": "Luota välityspalvelimen ympäristöön", @@ -2705,31 +2744,33 @@ "UI Scale": "käyttöliittymän koko", "Unarchive All": "Pura kaikkien arkistointi", "Unarchive Chat": "Pura keskustelun arkistointi", - "Unassigned": "", + "Unassigned": "Ei määritetty", "Underline": "Alleviivaus", - "unknown": "", + "unknown": "tuntematon", "Unknown": "Tuntematon", "Unknown User": "Tuntematon käyttäjä", "Unloads {{FROM_NOW}}": "Purkuja {{FROM_NOW}}", "Unmute": "Poista mykistys", "Unpin": "Irrota kiinnitys", "Unpin from Sidebar": "Irrota sivupalkista", - "Unshare All": "", - "Unshare All Shared Chats": "", + "Unread": "", + "Unshare All": "Lopeta kaikkien jakaminen", + "Unshare All Shared Chats": "Lopeta kaikkien jaettujen keskustelujen jakaminen", "Unshare Chat": "Lopeta keskustelun jakaminen", "Unsupported file type.": "Ei tuettu tiedostotyyppi", "Untagged": "Ei tageja", "Untitled": "Nimetön", "Update": "Päivitä", + "Update All Models": "", "Update and Copy Link": "Päivitä ja kopioi linkki", - "Update Email": "", - "Update embedding model": "", + "Update Email": "Päivitä sähköposti", + "Update embedding model": "Päivitä upotusmalli", "Update for the latest features and improvements.": "Päivitä uusimpiin ominaisuuksiin ja parannuksiin.", - "Update model": "", - "Update Name": "", + "Update model": "Päivitä malli", + "Update Name": "Päivitä nimi", "Update password": "Päivitä salasana", - "Update Picture": "", - "Update the password used for email and password sign-in.": "", + "Update Picture": "Päivitä kuva", + "Update the password used for email and password sign-in.": "Päivitä sähköposti- ja salasanakirjautumiseen käytetty salasana.", "Update your status": "Päivitä tilasi", "Updated": "Päivitetty", "Updated at": "Päivitetty", @@ -2744,13 +2785,13 @@ "Upload files": "Lataa tiedostoja", "Upload Files": "Lataa tiedostoja", "Upload Model": "Lataa malli", - "Upload or reset the image shown behind chat content.": "", - "Upload Photo": "", + "Upload or reset the image shown behind chat content.": "Lataa tai palauta keskustelun sisällön taustalla näkyvä kuva.", + "Upload Photo": "Lataa valokuva", "Upload Pipeline": "Lataa putki", "Upload profile image": "Lataa profiilikuva", "Upload Progress": "Latauksen edistyminen", "Uploaded files or images": "Ladatut tiedostot tai kuvat", - "Uploading": "", + "Uploading": "Ladataan", "Uploading {{current}}/{{total}}: {{file}}": "Ladataan {{current}}/{{total}}: {{file}}", "Uploading...": "Ladataan...", "URL": "URL", @@ -2760,69 +2801,76 @@ "Use": "Käytä", "Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.": "Käytä /v1/chat/completions-päätteitä/v1/audio/transcriptions-pääteen sijaan mahdollisesti paremman tarkkuuden saavuttamiseksi.", "Use a Gemini API key for image generation.": "", - "Use a valid event name or pattern like user.*": "", - "Use a wider chat layout on large displays.": "", - "Use an API key when your ComfyUI server requires one.": "", - "Use an LLM to improve tables, forms, math, and layout detection.": "", - "Use Base64": "", + "Use a valid event name or pattern like user.*": "Käytä kelvollista tapahtuman nimeä tai mallia, kuten user.*", + "Use a wider chat layout on large displays.": "Käytä laajempaa keskustelun asettelua suurilla näytöillä.", + "Use an API key when your ComfyUI server requires one.": "Käytä API-avainta, kun ComfyUI-palvelimesi vaatii sitä.", + "Use an LLM to improve tables, forms, math, and layout detection.": "Käytä LLM:ää parantamaan taulukoiden, lomakkeiden, matematiikan ja asettelun tunnistusta.", + "Use Base64": "Käytä Base64", "Use Chat Completions API": "Käytä Chat Completions API:a", - "Use device vibration feedback on supported Android devices.": "", + "Use device vibration feedback on supported Android devices.": "Käytä laitteen värinäpalautetta tuetuilla Android-laitteilla.", "Use discovered scopes": "", "Use groups to organize your users and assign permissions.": "Käytä ryhmiä käyttäjien järjestämiseen ja käyttöoikeuksien määrittämiseen.", "Use LLM": "Käytä LLM:ää", - "Use proxy environment variables to fetch page contents.": "", - "Use search results without fetching page contents.": "", - "Use segmented retrieval for focused and relevant content extraction.": "", - "Use segmented retrieval for focused and relevant context.": "", - "Use segmented retrieval for focused context.": "", - "Use styled formatting when exporting chats to PDF.": "", - "Use the active chat title as the browser tab title.": "", - "Use the rich composer instead of a plain textarea.": "", - "Use TLS when connecting to the LDAP server.": "", - "Use Web Search?": "", + "Use proxy environment variables to fetch page contents.": "Käytä välityspalvelimen ympäristömuuttujia sivun sisällön hakemiseen.", + "Use search results without fetching page contents.": "Käytä hakutuloksia hakematta sivujen sisältöjä.", + "Use segmented retrieval for focused and relevant content extraction.": "Käytä segmentoituja hakuja kohdennettuun ja relevanttiin sisällön poimintaan.", + "Use segmented retrieval for focused and relevant context.": "Käytä segmentoituja hakuja kohdennettuun ja relevanttiin kontekstin poimintaan.", + "Use segmented retrieval for focused context.": "Käytä segmentoituja hakuja kohdennettuun kontekstin poimintaan.", + "Use styled formatting when exporting chats to PDF.": "Käytä tyyliteltyä muotoilua viedessä keskusteluja PDF:ään.", + "Use the active chat title as the browser tab title.": "Käytä aktiivisen keskustelun otsikkoa selaimen välilehden otsikkona.", + "Use the rich composer instead of a plain textarea.": "Käytä rikasta tekstieditoria tavallisen tekstialueen sijaan.", + "Use these in model system prompts as {{example}}.": "", + "Use TLS when connecting to the LDAP server.": "Käytä TLS:ää yhdistäessäsi LDAP-palvelimeen.", + "Use Web Search?": "Käytä verkkohakua?", "user": "käyttäjä", "User": "Käyttäjä", "User Access": "", "User Activity": "Käyttäjätoiminta", - "User Connections": "", + "User Connections": "Käyttäjä yhteydet", "User Groups": "Käyttäjäryhmät", "User location successfully retrieved.": "Käyttäjän sijainti haettu onnistuneesti.", "User menu": "Käyttäjävalikko", - "User messages": "", + "User messages": "Käyttäjän viestit", "User Preview": "Käyttäjän esikatselu", "User ratings (thumbs up/down)": "Käyttäjien arviot (peukku ylös/alas)", "User Status": "Käyttäjän tila", + "User Variables": "", "User Webhooks": "Käyttäjän Webhook:it", "Username": "Käyttäjätunnus", "Username Claim": "", "users": "käyttäjät", "Users": "Käyttäjät", "Uses DefaultAzureCredential to authenticate": "Käyttää DefaultAzureCredential todentamiseen", - "Uses defaults": "", + "Uses defaults": "Käyttää oletuksia", "Uses OAuth 2.1 Dynamic Client Registration": "Käyttää OAuth 2.1 -dynaamista asiakasrekisteröintiä", "Using Entire Document": "Koko asiakirjan käyttäminen", "Using Focused Retrieval": "Kohdennetun haun käyttäminen", "Using the default arena model with all models. Click the plus button to add custom models.": "Käytetään oletusarena-mallia kaikkien mallien kanssa. Napsauta plus-painiketta lisätäksesi mukautettuja malleja.", - "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", - "Validate Certificate": "", - "Validate SSL certificates when fetching web content.": "", + "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "Kelvolliset aikayksiköt ovat 's', 'm', 'h', 'd', 'w' tai '-1', mikä tarkoittaa, ettei erääntymisaikaa ole.", + "Validate Certificate": "Tarkista varmenne", + "Validate SSL certificates when fetching web content.": "Tarkista SSL-varmenteet verkkosisällön haettaessa.", + "Value": "", "Valves": "Venttiilit", "Valves updated": "Venttiilit päivitetty", "Valves updated successfully": "Venttiilit päivitetty onnistuneesti", "variable": "muuttuja", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Tarkista yhteys", "Verify SSL Certificate": "Tarkista SSL-varmenne", - "Verify the LDAP server certificate when TLS is enabled.": "", + "Verify the LDAP server certificate when TLS is enabled.": "Tarkista LDAP-palvelimen varmenne, kun TLS on käytössä.", "Version": "Versio", "Version {{selectedVersion}} of {{totalVersions}}": "Versio {{selectedVersion}} / {{totalVersions}}", "Version deleted": "Versio poistettu", - "View chat": "", + "View chat": "Näytä keskustelu", "View Replies": "Näytä vastaukset", - "View Result from {{NAME}}": "", + "View Result from {{NAME}}": "Näytä tulos: {{NAME}}", "View source: {{name}}": "Näytä lähde: {{name}}", "View source: {{title}}": "Näytä lähde: {{title}}", - "View the installed version and check release updates.": "", + "View the installed version and check release updates.": "Näytä asennettu versio ja tarkista julkaisupäivitykset.", "Visibility": "Näkyvyys", "Visible": "Näkyvillä", "Visible to all users": "Näkyy kaikille käyttäjille", @@ -2832,8 +2880,8 @@ "Voice Input": "Äänitulolaitteen käyttö", "Voice mode": "Puhetila", "Voice Mode Prompt": "Puhetilan kehote", - "Wait for the current response to finish before compacting.": "", - "Wait for the current response to finish before forking.": "", + "Wait for the current response to finish before compacting.": "Odota nykyisen vastauksen valmistumista ennen tiivistämistä.", + "Wait for the current response to finish before forking.": "Odota nykyisen vastauksen valmistumista ennen haarauttamista.", "Waiting for upload...": "Odottaa latausta...", "Warning": "Varoitus", "Warning:": "Varoitus:", @@ -2845,15 +2893,15 @@ "Web API": "Web-API", "Web Loader Engine": "Verkkolataaja moottori", "Web Search": "Verkkohaku", - "Web Search Confirmation": "", - "Web Search Confirmation Content": "", + "Web Search Confirmation": "Verkkohakuvahvistus", + "Web Search Confirmation Content": "Verkkohakuvahvistuksen sisältö", "Web Search Engine": "Hakukoneet", "Web Search in Chat": "Verkkohaku keskustelussa", "Web Search Query Generation": "Verkkohakukyselyn luonti", "Webhook": "", - "Webhook deleted": "", + "Webhook deleted": "Webhook poistettu", "Webhook Name": "Webhook nimi", - "Webhook saved": "", + "Webhook saved": "Webhook tallennettu", "Webhooks": "Webhookit", "Webpage URLs": "Verkkosivujen verkko-osoitteet", "WebUI Settings": "WebUI-asetukset", @@ -2862,10 +2910,10 @@ "WebUI will make requests to \"{{url}}/api/chat\"": "WebUI lähettää pyyntöjä osoitteeseen \"{{url}}/api/chat\"", "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI lähettää pyyntöjä osoitteeseen \"{{url}}/chat/completions\"", "Week": "Viikko", - "Week of": "", + "Week of": "Viikko alkaen", "Weekly": "Viikoittain", - "Weekly at": "", - "Welcome to your AI home.": "", + "Weekly at": "Viikoittain", + "Welcome to your AI home.": "Tervetuloa tekoälykotiisi.", "What are you trying to achieve?": "Mitä yrität saavuttaa?", "What are you working on?": "Mitä olet työskentelemässä?", "What is NOT shared:": "Mitä EI jaeta:", @@ -2873,14 +2921,14 @@ "What's New in": "Mitä uutta", "What's on your mind?": "Mitä ajattelet?", "When": "Milloin", - "When disabled, keyboard shortcuts will not trigger any actions.": "", + "When disabled, keyboard shortcuts will not trigger any actions.": "Kun näppäimistön pikakomennot ovat pois käytöstä, ne eivät käynnistä mitään toimintoja.", "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.": "Kun käytössä, malli vastaa jokaiseen chatviestiin reaaliajassa, tuottaen vastauksen heti kun käyttäjä lähettää viestin. Tämä tila on hyödyllinen reaaliaikaisissa chat-sovelluksissa, mutta voi vaikuttaa suorituskykyyn hitaammilla laitteistoilla.", "Whisper (Local)": "Whisper (paikallinen)", "Who can share to this group": "Ketkä voivat jakaa tähän ryhmään", "Why?": "Miksi?", "Widescreen Mode": "Laajakuvatila", "Width": "Leveys", - "Width in pixels to compress images to. Leave empty for no compression.": "", + "Width in pixels to compress images to. Leave empty for no compression.": "Leveys pikseleinä, johon kuvat pakataan. Jätä tyhjäksi, jos et halua pakkausta.", "Wikipedia": "", "Won": "Voitti", "Working Directory": "Työhakemisto", @@ -2899,10 +2947,10 @@ "Yandex Web Search API Key": "Yandex Web Search API -avain", "Yandex Web Search config": "Yandex Web Search asetukset", "Yandex Web Search URL": "Yandex Web Search verkko-osoite", - "Yearly": "", + "Yearly": "Vuosittain", "Yesterday": "Eilen", "You": "Sinä", - "You are a sub-agent...": "", + "You are a sub-agent...": "Olet aliagentti...", "You are currently using a trial license. Please contact support to upgrade your license.": "Käytät tällä hetkellä kokeiluversiota. Ota yhteyttä tukeen lisenssin päivittämiseksi.", "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Voit keskustella enintään {{maxCount}} tiedoston kanssa kerralla.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Voit personoida vuorovaikutustasi LLM-ohjelmien kanssa lisäämällä muistoja 'Hallitse'-painikkeen kautta, jolloin ne ovat hyödyllisempiä ja räätälöityjä sinua varten.", @@ -2929,7 +2977,7 @@ "Your browser does not support the video tag.": "Selaimesi ei tue video-tagia.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Koko panoksesi menee suoraan lisäosan kehittäjälle; Open WebUI ei pidätä prosenttiosuutta. Valittu rahoitusalusta voi kuitenkin periä omia maksujaan.", "Your message text or inputs": "Viestisi teksti tai syöteet", - "Your query will be sent to the configured web search provider.": "", + "Your query will be sent to the configured web search provider.": "Kyselysi lähetetään määritetylle verkkohakupalveluntarjoajalle.", "Your usage stats have been successfully synced.": "Käyttötilastosi on synkronoitu onnistuneesti.", "YouTube": "YouTube", "Youtube Language": "Youtube kieli", diff --git a/src/lib/i18n/locales/fil-PH/translation.json b/src/lib/i18n/locales/fil-PH/translation.json index 291c109073..a1510ee7db 100644 --- a/src/lib/i18n/locales/fil-PH/translation.json +++ b/src/lib/i18n/locales/fil-PH/translation.json @@ -118,6 +118,7 @@ "Add to favorites": "", "Add User": "", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -191,6 +192,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -224,6 +226,7 @@ "and create a new shared link.": "", "Android": "", "Anyone": "Sinuman", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "", "API Key": "", @@ -289,6 +292,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -431,8 +435,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Mga Chat", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "", "Check for updates": "", @@ -440,6 +447,7 @@ "Choose a model before saving...": "", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -473,6 +481,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -564,6 +573,7 @@ "Confirm": "Kumpirmahin", "Confirm Password": "Kumpirmahin ang Password", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -720,6 +730,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -768,6 +779,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "", "Direct": "", @@ -839,6 +851,7 @@ "Download as SVG": "", "Download canceled": "", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -886,6 +899,7 @@ "Edit Terminal Connection": "", "Edit User": "", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -919,6 +933,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Pinagana", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1176,6 +1191,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "", "Failed to save models configuration": "", @@ -1243,6 +1259,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1290,6 +1307,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1468,6 +1486,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1541,9 +1560,9 @@ "List": "Listahan", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "", "Loaded": "", "Loader": "", @@ -1582,6 +1601,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marso", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1654,7 +1675,6 @@ "Model": "Modelo", "Model '{{modelName}}' has been successfully downloaded.": "", "Model '{{modelTag}}' is already in queue for downloading.": "", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "", "Model {{name}} is now {{status}}": "", @@ -1753,8 +1773,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1785,6 +1808,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1826,6 +1850,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1897,6 +1922,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1974,6 +2000,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2037,6 +2064,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2044,7 +2072,10 @@ "Previous 30 days": "Nakaraang 30 araw", "Previous 7 days": "Nakaraang 7 araw", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Pribado", "Private conversation between selected users": "", "Production version updated": "", @@ -2178,6 +2209,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "Tugon", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2186,6 +2218,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resulta", "RESULT": "", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2231,6 +2264,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Maghanap", @@ -2247,6 +2281,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2332,6 +2367,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Ipadala", "Send a Message": "Magpadala ng Mensahe", @@ -2452,6 +2488,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "May nangyaring mali :/", "Sonar": "", @@ -2488,6 +2525,7 @@ "STDOUT/STDERR": "", "Steps": "", "Stop": "Itigil", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "", @@ -2519,6 +2557,7 @@ "Support": "Suporta", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "I-sync", @@ -2717,6 +2756,7 @@ "Unmute": "", "Unpin": "I-unpin", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2724,6 +2764,7 @@ "Untagged": "", "Untitled": "", "Update": "I-update", + "Update All Models": "", "Update and Copy Link": "", "Update Email": "", "Update embedding model": "", @@ -2781,6 +2822,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "", @@ -2795,6 +2837,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "Katayuan ng Gumagamit", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2809,10 +2852,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/fr-CA/translation.json b/src/lib/i18n/locales/fr-CA/translation.json index e907727a56..dbe7d04a91 100644 --- a/src/lib/i18n/locales/fr-CA/translation.json +++ b/src/lib/i18n/locales/fr-CA/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Ajouter un utilisateur", "Add User Group": "Ajouter un groupe d'utilisateurs", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Autoriser l'emplacement de l'utilisateur", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "et créer un nouveau lien partagé.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL de base de l'API", "API Key": "Clé d'API", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "Autorisations de la conversation", "Chat Tags Auto-Generation": "Génération automatique des tags", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Conversations", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Vérifiez à nouveau.", "Check for updates": "Vérifier les mises à jour disponibles", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Choisissez un modèle avant de sauvegarder...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Effacer la mémoire", "Clear Memory": "Effacer la mémoire", @@ -571,6 +580,7 @@ "Confirm": "Confirmer", "Confirm Password": "Confirmer le mot de passe", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Confirmer votre action", "Confirm your new password": "Confirmer votre nouveau mot de passe", "Confirm Your Password": "", @@ -727,6 +737,7 @@ "Default to ALL": "Par défaut à TOUS", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "La recherche segmentée par défaut permet d'extraire un contenu ciblé et pertinent, ce qui est recommandé dans la plupart des cas.", + "Default Upload Mode": "", "Default User Role": "Rôle utilisateur par défaut", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Détection automatique des Artifacts", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dicter", "Didn't fully follow instructions": "N'a pas entièrement respecté les instructions", "Direct": "Direct", @@ -846,6 +858,7 @@ "Download as SVG": "Télécharger au format SVG", "Download canceled": "Téléchargement annulé", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Modifier l'utilisateur", "Edit User Group": "Modifier le groupe d'utilisateurs", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Activé", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "URL du point de terminaison", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Échec de la sauvegarde des connexions", "Failed to save conversation": "Échec de la sauvegarde de la conversation", "Failed to save models configuration": "Échec de la sauvegarde de la configuration des modèles", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Suivi", "Follow Up Generation": "Suivi de la génération", "Follow Up Generation Prompt": "Suivi de la génération du protompt", @@ -1299,6 +1316,7 @@ "Generate an image": "Génère une image", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Epingler dans la barre latérale", "Key": "Clé", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Connaissances", "Knowledge Access": "Accès aux connaissances", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Écoute en cours...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Les LLM peuvent faire des erreurs. Vérifiez les informations importantes.", "Loaded": "", "Loader": "Chargeur", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mars", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Modèle", "Model '{{modelName}}' has been successfully downloaded.": "Le modèle '{{modelName}}' a été téléchargé avec succès.", "Model '{{modelTag}}' is already in queue for downloading.": "Le modèle '{{modelTag}}' est déjà dans la file d'attente pour le téléchargement.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Le modèle {{modelName}} n'a pas de capacités visuelles", "Model {{name}} is now {{status}}": "Le modèle {{name}} est désormais {{status}}.", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "nouveau-canal", "Next message": "Message suivant", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Aucun utilisateur trouvé.", "No valves": "", "No valves to update": "Aucune vanne à mettre à jour", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Oups ! Des fichiers sont encore en cours de téléversement. Veuillez patienter jusqu'à la fin du téléversement.", "Oops! There was an error in the previous response.": "Oups ! Il y a eu une erreur dans la réponse précédente.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oups ! Vous utilisez une méthode non prise en charge (frontend uniquement). Veuillez servir l'interface Web à partir du backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Contenu de l'overlay utilisateur en attente", "Pending User Overlay Title": "Titre de l'overlay utilisateur en attente", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Accès aux appareils multimédias refusé", "Permission denied when accessing microphone": "Accès au microphone refusé", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID de préfixe", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Le préfixe ID est utilisé pour éviter les conflits avec d'autres connexions en ajoutant un préfixe aux ID de modèle - laissez vide pour désactiver", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Aperçu", @@ -2053,7 +2081,10 @@ "Previous 30 days": "30 derniers jours", "Previous 7 days": "7 derniers jours", "Previous message": "Message précédent", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privé", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Réinitialiser le stockage vectoriel/connaissances", "Reset view": "Réinitialiser la vue", "Response": "Réponse", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de réponse ne peuvent pas être activées car les autorisations du site web ont été refusées. Veuillez vérifier les réglages de votre navigateur pour accorder l'accès nécessaire.", "Response Splitting": "", "Response Watermark": "Filigramme de la réponse", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Résultat", "RESULT": "Résultat", + "Retained Messages": "", "Retrieval": "Récupération", "Retrieval Query Generation": "Génération de requête de RAG", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Défilement lors du changement de branche", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Recherche", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Filtres de recherche", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Les modèle(s) sélectionné(s) ne prennent pas en charge les entrées d'images", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Envoyer", "Send a Message": "Envoyer un message", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Ne pas utiliser le cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Stop", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Séquence d'arrêt", @@ -2530,6 +2568,7 @@ "Support": "Supporter", "Support this plugin:": "Supporter ce module", "Supported MIME Types": "Types MIME pris en charge", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "Désépingler", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "Pas de tag", "Untitled": "Sans titre", "Update": "Mise à jour", + "Update All Models": "", "Update and Copy Link": "Mettre à jour et copier le lien", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "utilisateur", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Webhooks utilisateur", "Username": "Nom d'utilisateur", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Vannes", "Valves updated": "Vannes mises à jour", "Valves updated successfully": "Les vannes ont été mises à jour avec succès", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Vérifier la connexion", "Verify SSL Certificate": "Vérifier le certificat SSL", diff --git a/src/lib/i18n/locales/fr-FR/translation.json b/src/lib/i18n/locales/fr-FR/translation.json index 15e4adf4cd..a3a9787590 100644 --- a/src/lib/i18n/locales/fr-FR/translation.json +++ b/src/lib/i18n/locales/fr-FR/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "Ajouter aux favoris", "Add User": "Ajouter un utilisateur", "Add User Group": "Ajouter un groupe d'utilisateurs", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Ajouter une page web", "Add your Open Terminal URL and API key in Settings → Integrations.": "Ajoutez votre URL Open Terminal et votre clé API dans Réglages → Intégrations.", @@ -197,6 +198,7 @@ "Allow User Location": "Autoriser l'emplacement de l'utilisateur", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "et créer un nouveau lien partagé.", "Android": "Android", "Anyone": "Tout le monde", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL de base de l'API", "API Key": "Clé API", @@ -295,6 +298,7 @@ "At time of event": "Au moment de l'événement", "Attach File From Knowledge": "Joindre un fichier depuis les connaissances", "Attach Files": "Joindre des fichiers", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Joindre une connaissance", "Attach Notes": "Joindre une note", "Attach Webpage": "Joindre une page web", @@ -437,8 +441,11 @@ "Chat Permissions": "Autorisations de la conversation", "Chat Tags Auto-Generation": "Génération automatique des tags", "Chat unshared successfully.": "Conversation non partagée avec succès.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "conversations", "Chats": "Conversations", + "Chats Open Sharing": "", "Chats Public Sharing": "Partage public des conversations", "Check Again": "Vérifiez à nouveau.", "Check for updates": "Vérifier les mises à jour disponibles", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Choisissez un modèle avant de sauvegarder...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Effacer la mémoire", "Clear Memory": "Effacer la mémoire", @@ -571,6 +580,7 @@ "Confirm": "Confirmer", "Confirm Password": "Confirmer le mot de passe", "Confirm Prompt from Embed": "Confirmer le prompt de l'embed", + "Confirm recording": "", "Confirm your action": "Confirmer votre action", "Confirm your new password": "Confirmer votre nouveau mot de passe", "Confirm Your Password": "Confirmez votre mot de passe", @@ -727,6 +737,7 @@ "Default to ALL": "Par défaut à TOUS", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "La recherche segmentée par défaut permet d'extraire un contenu ciblé et pertinent, ce qui est recommandé dans la plupart des cas.", + "Default Upload Mode": "", "Default User Role": "Rôle utilisateur par défaut", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "Désélectionner", "Detect Artifacts Automatically": "Détection automatique des Artifacts", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dicter", "Didn't fully follow instructions": "N'a pas entièrement respecté les instructions", "Direct": "Direct", @@ -846,6 +858,7 @@ "Download as SVG": "Télécharger au format SVG", "Download canceled": "Téléchargement annulé", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "Modifier la connexion à un terminal", "Edit User": "Modifier l'utilisateur", "Edit User Group": "Modifier le groupe d'utilisateurs", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Modifier le contenu de workflow.json", "edited": "édité", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Activer, désactiver ou personnaliser les balises de raisonnement utilisées par le modèle. « Activé » utilise les balises par défaut, « Désactivé » désactive les balises de raisonnement, et « Sur mesure » permet de spécifier vos propres balises de début et de fin.", "Enabled": "Activé", + "End call": "", "End Tag": "Tag de fin", "Endpoint": "", "Endpoint URL": "URL du point de terminaison", @@ -1185,6 +1200,7 @@ "Failed to remove member": "Échec de la suppression du membre", "Failed to render diagram": "Échec du rendu du diagramme", "Failed to render visualization": "Échec du rendu de la visualisation", + "Failed to save chat variables": "", "Failed to save connections": "Échec de la sauvegarde des connexions", "Failed to save conversation": "Échec de la sauvegarde de la conversation", "Failed to save models configuration": "Échec de la sauvegarde de la configuration des modèles", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "Dossier mis à jour avec succès", "Folders": "Dossiers", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Questions de suivi", "Follow Up Generation": "Génération de questions de suivi", "Follow Up Generation Prompt": "Prompt de génération de questions de suivi", @@ -1299,6 +1316,7 @@ "Generate an image": "Génère une image", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Créer et modifier des images", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Générer une paire de messages", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Epingler dans la barre latérale", "Key": "Clé", "Key is required": "La clé est requise", + "key_name": "", "Keyboard": "", "Knowledge": "Connaissances", "Knowledge Access": "Accès aux connaissances", @@ -1550,9 +1569,9 @@ "List": "Liste", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Écoute en cours...", + "LiteLLM": "", "Live": "Actif", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Les LLM peuvent faire des erreurs. Vérifiez les informations importantes.", "Loaded": "", "Loader": "Chargeur", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mars", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Découpage par en-têtes markdown", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Modèle", "Model '{{modelName}}' has been successfully downloaded.": "Le modèle '{{modelName}}' a été téléchargé avec succès.", "Model '{{modelTag}}' is already in queue for downloading.": "Le modèle '{{modelTag}}' est déjà dans la file d'attente pour le téléchargement.", - "Model {{modelId}} not found": "Le modèle {{modelId}} est introuvable", "Model {{modelName}} deleted successfully": "Le modèle {{modelName}} a été supprimé avec succès", "Model {{modelName}} is not vision capable": "Le modèle {{modelName}} n'a pas de fonctionnalité de vision", "Model {{name}} is now {{status}}": "Le modèle {{name}} est désormais {{status}}.", @@ -1762,8 +1782,11 @@ "New Webhook": "Nouveau webhook", "new-channel": "nouveau-canal", "Next message": "Message suivant", + "Next month": "", "Next page": "", "Next run": "Prochaine exécution", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Aucun partage. Visible uniquement par vous.", "No actions found": "", "No activity data": "Aucune activité", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "Aucun fichier dans cette base de connaissances.", "No files yet. Upload files or run Python code to create them.": "Aucun fichier pour le moment. Téléversez des fichiers ou exécutez du code Python pour en créer.", "No filters found": "", + "No folders": "", "No functions found": "Aucune fonction trouvée", "No groups found": "Aucun groupe trouvé", "No history available": "Aucun historique disponible", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "Aucun outil trouvé", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Aucun utilisateur trouvé.", "No valves": "Aucune vanne trouvée", "No valves to update": "Aucune vanne à mettre à jour", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Oups ! Des fichiers sont encore en cours de téléversement. Veuillez patienter jusqu'à la fin du téléversement.", "Oops! There was an error in the previous response.": "Oups ! Il y a eu une erreur dans la réponse précédente.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oups ! Vous utilisez une méthode non prise en charge (frontend uniquement). Veuillez servir l'interface Web à partir du backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Contenu de l'overlay utilisateur en attente", "Pending User Overlay Title": "Titre de l'overlay utilisateur en attente", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Accès aux appareils multimédias refusé", "Permission denied when accessing microphone": "Accès au microphone refusé", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID de préfixe", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Le préfixe ID est utilisé pour éviter les conflits avec d'autres connexions en ajoutant un préfixe aux ID de modèle - laissez vide pour désactiver", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Empêcher la création de fichier", "Preview": "Aperçu", @@ -2053,7 +2081,10 @@ "Previous 30 days": "30 derniers jours", "Previous 7 days": "7 derniers jours", "Previous message": "Message précédent", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privé", "Private conversation between selected users": "Conversation privée entre les utilisateurs sélectionnés", "Production version updated": "Version active mise à jour", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Réinitialiser le stockage vectoriel/connaissances", "Reset view": "Réinitialiser la vue", "Response": "Réponse", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de réponse ne peuvent pas être activées car les autorisations du site web ont été refusées. Veuillez vérifier les réglages de votre navigateur pour accorder l'accès nécessaire.", "Response Splitting": "", "Response Watermark": "Filigramme de la réponse", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Résultat", "RESULT": "Résultat", + "Retained Messages": "", "Retrieval": "Récupération", "Retrieval Query Generation": "Génération de requête de RAG", "Retrieved {{count}} sources": "Sources récupérées : {{count}}", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "L'heure prévue doit être située dans le futur", "Scopes": "", "Scroll On Branch Change": "Défilement lors du changement de branche", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Retour en haut", "Search": "Recherche", @@ -2258,6 +2292,7 @@ "Search Files": "Rechercher des fichiers", "Search filters": "", "Search Filters": "Filtres de recherche", + "Search folders": "", "search for archived chats": "Rechercher les conversations archivées", "search for folders": "Rechercher tous les dossiers", "search for pinned chats": "Rechercher les conversations épinglées", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "Modèle sélectionné : {{modelName}}", "Selected model(s) do not support image inputs": "Les modèle(s) sélectionné(s) ne prennent pas en charge les entrées d'images", + "Selected models define incompatible Chat Variables.": "", "semantic": "sémantique", "Send": "Envoyer", "Send a Message": "Envoyer un message", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "Partage public des skills", "Skills Sharing": "Partage des skills", "Skip Cache": "Ne pas utiliser le cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Quelque chose s'est mal passé :/", "Sonar": "Sonar", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Étapes", "Stop": "Stop", + "Stop camera": "", "Stop Download": "Arrêter le téléchargement", "Stop Generating": "Arrêter la génération", "Stop Sequence": "Séquence d'arrêt", @@ -2530,6 +2568,7 @@ "Support": "Supporter", "Support this plugin:": "Supporter ce module", "Supported MIME Types": "Types MIME pris en charge", + "Switch camera": "", "Switch to JSON editor": "Passer à l'éditeur JSON", "Switch to visual editor": "Passer à l'éditeur visuel", "Sync": "Synchroniser", @@ -2728,6 +2767,7 @@ "Unmute": "Activer le son", "Unpin": "Désépingler", "Unpin from Sidebar": "Désépingler de la barre latérale", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Annuler le partage de la conversation", @@ -2735,6 +2775,7 @@ "Untagged": "Pas de tag", "Untitled": "Sans titre", "Update": "Mise à jour", + "Update All Models": "", "Update and Copy Link": "Mettre à jour et copier le lien", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "utilisateur", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Évaluations des utilisateurs (pouces vers le haut/bas)", "User Status": "Statut utilisateur", + "User Variables": "", "User Webhooks": "Webhooks utilisateur", "Username": "Nom d'utilisateur", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Vannes", "Valves updated": "Vannes mises à jour", "Valves updated successfully": "Vannes mises à jour avec succès", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Vérifier la connexion", "Verify SSL Certificate": "Vérifier le certificat SSL", diff --git a/src/lib/i18n/locales/gl-ES/translation.json b/src/lib/i18n/locales/gl-ES/translation.json index 0fe5637533..549343f8c5 100644 --- a/src/lib/i18n/locales/gl-ES/translation.json +++ b/src/lib/i18n/locales/gl-ES/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Agregar Usuario", "Add User Group": "Agregar usuario al grupo", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Permitir Ubicación do Usuario", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "e xerar un novo enlace compartido.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Dirección URL da API", "API Key": "Chave da API ", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Permisos do Chat", "Chat Tags Auto-Generation": "Auto-xeneración das Etiquetas para o Chat", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Verifica de novo", "Check for updates": "Verificar actualizacions", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Escolle un modelo antes de gardar os cambios...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Liberar memoria", "Clear Memory": "Limpar memoria", @@ -563,6 +572,7 @@ "Confirm": "Confirmar", "Confirm Password": "Confirmar Contrasinal ", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Confirma a tua acción", "Confirm your new password": "Confirmar o teu novo contrasinal ", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "Predeterminado a TODOS", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Rol por defecto para os usuarios", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Non sigueu as instruccions", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "Descarga cancelada", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Editar Usuario", "Edit User Group": "Editar grupo de usuarios", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Activado", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Non puido gardarse a conversa", "Failed to save models configuration": "Non pudogardarse a configuración de os modelos", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "Generar unha imaxen", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Chave", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "coñecemento", "Knowledge Access": "Acceso al coñecemento", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Escoitando...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Os LLM poden cometer erros. Verifica a información importante.", "Loaded": "", "Loader": "Cargador", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marzo", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Modelo", "Model '{{modelName}}' has been successfully downloaded.": "0 modelo '{{modelName}}' se ha descargado correctamente.", "Model '{{modelTag}}' is already in queue for downloading.": "0 modelo '{{modelTag}}' ya está en cola para descargar.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "O modelo {{modelName}} no es capaz de ver", "Model {{name}} is now {{status}}": "O modelo {{name}} ahora es {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "novo-canal", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "No se encontraron usuarios.", "No valves": "", "No valves to update": "Non ten válvulas para actualizar", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "¡Ups! Todavía hay arquivos subiendo. Por favor, espere a que a subida se complete.", "Oops! There was an error in the previous response.": "¡Ups! Hubo un error en a resposta anterior.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "¡Ups! Estás utilizando un método no compatible (solo frontend). Por favor ejecute a WebUI desde o backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Permiso denegado al acceder a os dispositivos", "Permission denied when accessing microphone": "Permiso denegado al acceder a a micrófono", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID de prefijo", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "O ID de prefixo se utiliza para evitar conflictos con outras conexiones añadiendo un prefijo a os IDs de os modelos - deje vacío para deshabilitar", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Últimos 30 días", "Previous 7 days": "Últimos 7 días", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Reiniciar almacenamiento de vectores/coñecemento", "Reset view": "Reiniciar vista", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "As notificacions de resposta non poden activarse debido a que os permisos do sitio web han sido denegados. Por favor, visite as configuracions da sua navegador para otorgar o acceso necesario.", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultado", "RESULT": "Resultado", + "Retained Messages": "", "Retrieval": "recuperación", "Retrieval Query Generation": "xeneración de consulta de recuperación", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Buscar", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Filtros de búsqueda", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Os modelos seleccionados no admiten entradas de imaxen", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Enviar", "Send a Message": "Enviar un mensaxe", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Detener", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Detener secuencia", @@ -2516,6 +2554,7 @@ "Support": "Soporte", "Support this plugin:": "Brinda soporte a este plugin:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Desanclar", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Sin etiquetar", "Untitled": "", "Update": "Actualizar", + "Update All Models": "", "Update and Copy Link": "Actualizar y copiar enlace", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "usuario", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Nombre de usuario", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves actualizados", "Valves updated successfully": "Valves actualizados con éxito", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/he-IL/translation.json b/src/lib/i18n/locales/he-IL/translation.json index 9b0c07c0ac..cc3ae320b8 100644 --- a/src/lib/i18n/locales/he-IL/translation.json +++ b/src/lib/i18n/locales/he-IL/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "הוסף משתמש", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "וצור קישור משותף חדש.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "כתובת URL בסיסית ל-API", "API Key": "מפתח API", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "צ'אטים", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "בדוק שוב", "Check for updates": "בדוק עדכונים", @@ -446,6 +453,7 @@ "Choose a model before saving...": "בחר מודל לפני השמירה...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "נקה זיכרון", "Clear Memory": "נקה", @@ -571,6 +580,7 @@ "Confirm": "", "Confirm Password": "אשר סיסמה", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "אשר את הפעולה שלך", "Confirm your new password": "אשר את הסיסמה החדשה שלך", "Confirm Your Password": "", @@ -727,6 +737,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "תפקיד משתמש ברירת מחדל", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "לא עקב אחרי ההוראות באופן מלא", "Direct": "", @@ -846,6 +858,7 @@ "Download as SVG": "", "Download canceled": "ההורדה בוטלה", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "ערוך משתמש", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "מופעל", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "שמירת השיחה נכשלה", "Failed to save models configuration": "", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1299,6 +1316,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "מודלים בשפה טבעית יכולים לטעות. אמת מידע חשוב.", "Loaded": "", "Loader": "", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "מרץ", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "המודל '{{modelName}}' הורד בהצלחה.", "Model '{{modelTag}}' is already in queue for downloading.": "המודל '{{modelTag}}' כבר בתור להורדה.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "דגם {{modelName}} אינו בעל יכולת ראייה", "Model {{name}} is now {{status}}": "דגם {{name}} הוא כעת {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "לא נמצאו יוזרים", "No valves": "", "No valves to update": "", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "אופס! אתה משתמש בשיטה לא נתמכת (רק חזית). אנא שרת את ממשק המשתמש האינטרנטי מהשרת האחורי.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2053,7 +2081,10 @@ "Previous 30 days": "30 הימים הקודמים", "Previous 7 days": "7 הימים הקודמים", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "תוצאה", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "חפש", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "דגמים נבחרים אינם תומכים בקלט תמונה", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "שלח", "Send a Message": "שלח הודעה", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "סידור עצירה", @@ -2530,6 +2568,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "עדכן ושכפל קישור", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "משתמש", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "משתנה", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/hi-IN/translation.json b/src/lib/i18n/locales/hi-IN/translation.json index b9307ea9ea..2d14810a60 100644 --- a/src/lib/i18n/locales/hi-IN/translation.json +++ b/src/lib/i18n/locales/hi-IN/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "उपयोगकर्ता जोड़ें", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "और एक नई साझा लिंक बनाएं.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "एपीआई बेस यूआरएल", "API Key": "एपीआई कुंजी", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "सभी चैट", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "फिर से जाँचो", "Check for updates": "अपडेट के लिए जाँच", @@ -439,6 +446,7 @@ "Choose a model before saving...": "सहेजने से पहले एक मॉडल चुनें...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "पासवर्ड की पुष्टि कीजिये", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "डिफ़ॉल्ट उपयोगकर्ता भूमिका", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "निर्देशों का पूरी तरह से पालन नहीं किया", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "डाउनलोड रद्द किया गया", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "यूजर को संपादित करो", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "सक्षम", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "वार्तालाप सहेजने में विफल", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "एलएलएम गलतियाँ कर सकते हैं। महत्वपूर्ण जानकारी सत्यापित करें.", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "मार्च", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "मॉडल '{{modelName}}' सफलतापूर्वक डाउनलोड हो गया है।", "Model '{{modelTag}}' is already in queue for downloading.": "मॉडल '{{modelTag}}' पहले से ही डाउनलोड करने के लिए कतार में है।", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "मॉडल {{modelName}} दृष्टि सक्षम नहीं है", "Model {{name}} is now {{status}}": "मॉडल {{name}} अब {{status}} है", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "उफ़! आप एक असमर्थित विधि (केवल फ्रंटएंड) का उपयोग कर रहे हैं। कृपया बैकएंड से WebUI सर्वे करें।", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "पिछले 30 दिन", "Previous 7 days": "पिछले 7 दिन", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "परिणाम", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "खोजें", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "चयनित मॉडल छवि इनपुट का समर्थन नहीं करते हैं", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "भेज", "Send a Message": "एक संदेश भेजो", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "अनुक्रम रोकें", @@ -2516,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "अपडेट करें और लिंक कॉपी करें", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "उपयोगकर्ता", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "वेरिएबल", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/hr-HR/translation.json b/src/lib/i18n/locales/hr-HR/translation.json index 4d96a0f6c1..bd2ee5cbd9 100644 --- a/src/lib/i18n/locales/hr-HR/translation.json +++ b/src/lib/i18n/locales/hr-HR/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Dodaj korisnika", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "i stvorite novu dijeljenu vezu.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Osnovni URL API-ja", "API Key": "API ključ", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Razgovori", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Provjeri ponovo", "Check for updates": "Provjeri za ažuriranja", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Odaberite model prije spremanja...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Očisti memoriju", "Clear Memory": "", @@ -571,6 +580,7 @@ "Confirm": "", "Confirm Password": "Potvrdite lozinku", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -727,6 +737,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Zadana korisnička uloga", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Nije u potpunosti slijedio upute", "Direct": "", @@ -846,6 +858,7 @@ "Download as SVG": "", "Download canceled": "Preuzimanje otkazano", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Uredi korisnika", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Omogućeno", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Neuspješno spremanje razgovora", "Failed to save models configuration": "", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1299,6 +1316,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Znanje", "Knowledge Access": "", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Slušam...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM-ovi mogu pogriješiti. Provjerite važne informacije.", "Loaded": "", "Loader": "", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Ožujak", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' je uspješno preuzet.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' je već u redu za preuzimanje.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} ne čita vizualne impute", "Model {{name}} is now {{status}}": "Model {{name}} sada je {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Koristite nepodržanu metodu (samo frontend). Molimo poslužite WebUI s backend-a.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Dopuštenje je odbijeno prilikom pristupa medijskim uređajima", "Permission denied when accessing microphone": "Dopuštenje je odbijeno prilikom pristupa mikrofonu", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Prethodnih 30 dana", "Previous 7 days": "Prethodnih 7 dana", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "REZULTAT", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Pretraga", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Odabrani modeli ne podržavaju unose slika", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Pošalji", "Send a Message": "Pošaljite poruku", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Zaustavi sekvencu", @@ -2530,6 +2568,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "Ažuriraj i kopiraj vezu", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "korisnik", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "varijabla", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/hu-HU/translation.json b/src/lib/i18n/locales/hu-HU/translation.json index 38aace757a..3488d20b99 100644 --- a/src/lib/i18n/locales/hu-HU/translation.json +++ b/src/lib/i18n/locales/hu-HU/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Felhasználó hozzáadása", "Add User Group": "Felhasználói csoport hozzáadása", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Felhasználói helyzet engedélyezése", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "és hozz létre egy új megosztott linket.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API alap URL", "API Key": "API kulcs", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Beszélgetési engedélyek", "Chat Tags Auto-Generation": "Beszélgetés címkék automatikus generálása", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Beszélgetések", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Ellenőrzés újra", "Check for updates": "Frissítések keresése", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Válassz modellt mentés előtt...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Memória törlése", "Clear Memory": "Memória törlése", @@ -563,6 +572,7 @@ "Confirm": "Megerősítés", "Confirm Password": "Jelszó megerősítése", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Erősítsd meg a műveletet", "Confirm your new password": "Erősítsd meg az új jelszavad", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "Alapértelmezés szerint MIND", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Alapértelmezés szerint szegmentált visszakeresés a fókuszált és releváns tartalom kinyeréséhez, ez a legtöbb esetben ajánlott.", + "Default Upload Mode": "", "Default User Role": "Alapértelmezett felhasználói szerep", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Nem követte teljesen az utasításokat", "Direct": "Közvetlen", @@ -838,6 +850,7 @@ "Download as SVG": "Letöltés SVG-ként", "Download canceled": "Letöltés megszakítva", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Felhasználó szerkesztése", "Edit User Group": "Felhasználói csoport szerkesztése", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Engedélyezve", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Nem sikerült menteni a kapcsolatokat", "Failed to save conversation": "Nem sikerült menteni a beszélgetést", "Failed to save models configuration": "Nem sikerült menteni a modellek konfigurációját", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "Kép generálása", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Kulcs", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Tudásbázis", "Knowledge Access": "Tudásbázis hozzáférés", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Hallgatás...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Az LLM-ek hibázhatnak. Ellenőrizze a fontos információkat.", "Loaded": "", "Loader": "Betöltő", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Március", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Modell", "Model '{{modelName}}' has been successfully downloaded.": "A '{{modelName}}' modell sikeresen letöltve.", "Model '{{modelTag}}' is already in queue for downloading.": "A '{{modelTag}}' modell már a letöltési sorban van.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "A {{modelName}} modell nem képes képfeldolgozásra", "Model {{name}} is now {{status}}": "A {{name}} modell most {{status}} állapotban van", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "új csatorna", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Nem található felhasználó.", "No valves": "", "No valves to update": "Nincs frissítendő szelep", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Hoppá! Még vannak feltöltés alatt álló fájlok. Kérjük, várja meg a feltöltés befejezését.", "Oops! There was an error in the previous response.": "Hoppá! Hiba történt az előző válaszban.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hoppá! Nem támogatott módszert használ (csak frontend). Kérjük, szolgálja ki a WebUI-t a backend-ről.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Hozzáférés megtagadva a médiaeszközökhöz", "Permission denied when accessing microphone": "Hozzáférés megtagadva a mikrofonhoz", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Előtag azonosító", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Az előtag azonosító a modell azonosítókhoz hozzáadott előtag segítségével elkerüli az egyéb kapcsolatokkal való ütközéseket - hagyja üresen a letiltáshoz", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Előző 30 nap", "Previous 7 days": "Előző 7 nap", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privát", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Vektor tárhely/tudásbázis visszaállítása", "Reset view": "Nézet visszaállítása", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "A válasz értesítések nem aktiválhatók, mert a weboldal engedélyei meg lettek tagadva. Kérjük, látogasson el a böngésző beállításaihoz a szükséges hozzáférés megadásához.", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Eredmény", "RESULT": "Eredmény", + "Retained Messages": "", "Retrieval": "Visszakeresés", "Retrieval Query Generation": "Visszakeresési lekérdezés generálása", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Keresés", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Keresési szűrők", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "A kiválasztott modell(ek) nem támogatják a képbemenetet", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Küldés", "Send a Message": "Üzenet küldése", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Leállítás", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Leállítási szekvencia", @@ -2516,6 +2554,7 @@ "Support": "Támogatás", "Support this plugin:": "Támogassa ezt a bővítményt:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Rögzítés feloldása", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Címkézetlen", "Untitled": "", "Update": "Frissítés", + "Update All Models": "", "Update and Copy Link": "Frissítés és link másolása", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "felhasználó", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Felhasználói webhookok", "Username": "Felhasználónév", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Szelepek", "Valves updated": "Szelepek frissítve", "Valves updated successfully": "Szelepek sikeresen frissítve", "variable": "változó", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Kapcsolat ellenőrzése", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/id-ID/translation.json b/src/lib/i18n/locales/id-ID/translation.json index ed1b461a27..5b03b700f6 100644 --- a/src/lib/i18n/locales/id-ID/translation.json +++ b/src/lib/i18n/locales/id-ID/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "", "Add User": "Tambah Pengguna", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -183,6 +184,7 @@ "Allow User Location": "Izinkan Lokasi Pengguna", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "dan membuat tautan bersama baru.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Dasar API", "API Key": "Kunci API", @@ -281,6 +284,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -423,8 +427,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Obrolan", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Periksa Lagi", "Check for updates": "Memeriksa pembaruan", @@ -432,6 +439,7 @@ "Choose a model before saving...": "Pilih model sebelum menyimpan...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Menghapus memori", "Clear Memory": "", @@ -555,6 +564,7 @@ "Confirm": "Konfirmasi", "Confirm Password": "Konfirmasi Kata Sandi", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Konfirmasi tindakan Anda", "Confirm your new password": "", "Confirm Your Password": "", @@ -711,6 +721,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Peran Pengguna Default", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Tidak sepenuhnya mengikuti instruksi", "Direct": "", @@ -830,6 +842,7 @@ "Download as SVG": "", "Download canceled": "Unduh dibatalkan", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "", "Edit User": "Edit Pengguna", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Diaktifkan", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1165,6 +1180,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Gagal menyimpan percakapan", "Failed to save models configuration": "", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1279,6 +1296,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Pengetahuan", "Knowledge Access": "", @@ -1530,9 +1549,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Mendengarkan", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM dapat membuat kesalahan. Verifikasi informasi penting.", "Loaded": "", "Loader": "", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Maret", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' telah berhasil diunduh.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' sudah berada dalam antrean untuk diunduh.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} tidak dapat dilihat", "Model {{name}} is now {{status}}": "Model {{name}} sekarang menjadi {{status}}", @@ -1742,8 +1762,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1815,6 +1839,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "Tidak ada katup untuk diperbarui", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Anda menggunakan metode yang tidak didukung (hanya untuk frontend). Silakan sajikan WebUI dari backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Izin ditolak saat mengakses perangkat media", "Permission denied when accessing microphone": "Izin ditolak saat mengakses mikrofon", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2033,7 +2061,10 @@ "Previous 30 days": "30 hari sebelumnya", "Previous 7 days": "7 hari sebelumnya", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Notifikasi respons tidak dapat diaktifkan karena izin situs web telah ditolak. Silakan kunjungi pengaturan browser Anda untuk memberikan akses yang diperlukan.", "Response Splitting": "", "Response Watermark": "", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "HASIL", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Cari", @@ -2232,6 +2266,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Model yang dipilih tidak mendukung input gambar", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Kirim", "Send a Message": "Kirim Pesan", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Hentikan Urutan", @@ -2502,6 +2540,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2700,6 +2739,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2707,6 +2747,7 @@ "Untagged": "", "Untitled": "", "Update": "Memperbarui", + "Update All Models": "", "Update and Copy Link": "Perbarui dan Salin Tautan", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "pengguna", @@ -2778,6 +2820,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Katup", "Valves updated": "Katup diperbarui", "Valves updated successfully": "Katup berhasil diperbarui", "variable": "variabel", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/ie-GA/translation.json b/src/lib/i18n/locales/ie-GA/translation.json index 1cf9445661..252b0fce76 100644 --- a/src/lib/i18n/locales/ie-GA/translation.json +++ b/src/lib/i18n/locales/ie-GA/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Cuir le Ceanáin", "Add User": "Cuir Úsáideoir leis", "Add User Group": "Cuir Grúpa Úsáideoirí leis", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Cuir leathanach gréasáin leis", "Add your Open Terminal URL and API key in Settings → Integrations.": "Cuir d’URL Teirminéal Oscailte agus d’eochair API leis i Socruithe → Comhtháthúcháin.", @@ -190,6 +191,7 @@ "Allow User Location": "Ceadaigh Suíomh Úsáideora", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "agus cruthaigh nasc nua roinnte.", "Android": "Android", "Anyone": "Aon duine", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Bonn API", "API Key": "Eochair API", @@ -288,6 +291,7 @@ "At time of event": "Tráth na hócáide", "Attach File From Knowledge": "Ceangail Comhad ó Eolas", "Attach Files": "Ceangail Comhaid", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Ceangail Eolas", "Attach Notes": "Ceangail Nótaí", "Attach Webpage": "Ceangail Leathanach Gréasáin", @@ -430,8 +434,11 @@ "Chat Permissions": "Ceadanna Comhrá", "Chat Tags Auto-Generation": "Clibeanna Comhrá Auto-Giniúint", "Chat unshared successfully.": "Comhrá díroinnte go rathúil.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "comhráite", "Chats": "Comhráite", + "Chats Open Sharing": "", "Chats Public Sharing": "Comhráite Comhroinnt Phoiblí", "Check Again": "Seiceáil Arís", "Check for updates": "Seiceáil nuashonruithe", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Roghnaigh samhail sula sábhálann tú...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Cuimhne ghlan", "Clear Memory": "Glan Cuimhne", @@ -563,6 +572,7 @@ "Confirm": "Deimhnigh", "Confirm Password": "Deimhnigh Pasfhocal", "Confirm Prompt from Embed": "Deimhnigh Treoir ón Leabú", + "Confirm recording": "", "Confirm your action": "Deimhnigh do ghníomh", "Confirm your new password": "Deimhnigh do phasfhocal nua", "Confirm Your Password": "Deimhnigh Do Phasfhocal", @@ -719,6 +729,7 @@ "Default to ALL": "Réamhshocrú do GACH", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Réamhshocrú maidir le haisghabháil deighilte d'eastóscadh ábhar dírithe agus ábhartha, moltar é seo i bhformhór na gcásanna.", + "Default Upload Mode": "", "Default User Role": "Ról Úsáideora Réamhshocraithe", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "Díroghnaigh", "Detect Artifacts Automatically": "Déan Déantáin a bhrath go huathoibríoch", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Deachtaigh", "Didn't fully follow instructions": "Níor lean sé treoracha go hiomlán", "Direct": "Díreach", @@ -838,6 +850,7 @@ "Download as SVG": "Íoslódáil i SVG", "Download canceled": "Íoslódáil cealaithe", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Cuir Nasc Críochfoirt in Eagar", "Edit User": "Cuir Úsáideoir in eagar", "Edit User Group": "Cuir Grúpa Úsáideoirí in Eagar", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Cuir ábhar workflow.json in eagar", "edited": "curtha in eagar", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Cumasaigh, díchumasaigh nó saincheap na clibeanna réasúnaíochta a úsáideann an tsamhail. Úsáideann \"Cumasaithe\" clibeanna réamhshocraithe, múchann \"Díchumasaithe\" clibeanna réasúnaíochta, agus ligeann \"Saincheaptha\" duit do chlibeanna tosaigh agus deiridh féin a shonrú.", "Enabled": "Cumasaithe", + "End call": "", "End Tag": "Clib Deiridh", "Endpoint": "", "Endpoint URL": "URL críochphointe", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Theip ar an mball a bhaint", "Failed to render diagram": "Theip ar an léaráid a rindreáil", "Failed to render visualization": "Theip ar an léirshamhlú a rindreáil", + "Failed to save chat variables": "", "Failed to save connections": "Theip ar na naisc a shábháil", "Failed to save conversation": "Theip ar an gcomhrá a shábháil", "Failed to save models configuration": "Theip ar chumraíocht na samhlacha a shábháil", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Nuashonraíodh an fillteán go rathúil", "Folders": "Fillteáin", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Leanúint suas", "Follow Up Generation": "Giniúint Leantach", "Follow Up Generation Prompt": "Treoir Giniúna Leantach", @@ -1289,6 +1306,7 @@ "Generate an image": "Gin íomhá", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Íomhánna a ghiniúint agus a chur in eagar", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Gin Péire Teachtaireachta", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Coinnigh sa Bharra Taobh", "Key": "Eochair", "Key is required": "Tá eochair ag teastáil", + "key_name": "", "Keyboard": "", "Knowledge": "Eolas", "Knowledge Access": "Rochtain Eolais", @@ -1540,9 +1559,9 @@ "List": "Liosta", "List calendars, search, create, update, and delete calendar events": "Liostaigh féilirí, cuardaigh, cruthaigh, nuashonraigh agus scrios imeachtaí féilire", "Listening...": "Éisteacht...", + "LiteLLM": "", "Live": "Beo", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Is féidir le LLManna botúin a dhéanamh. Fíoraigh faisnéis thábhachtach.", "Loaded": "Luchtaithe", "Loader": "Lódóir", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Márta", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Marcáil síos", "Markdown Header Text Splitter": "Scoilteoir Téacs Ceanntásc Markdown", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Samhail", "Model '{{modelName}}' has been successfully downloaded.": "Rinneadh an tsamhail '{{modelName}}' a íoslódáil go rathúil.", "Model '{{modelTag}}' is already in queue for downloading.": "Tá samhail '{{modelTag}}' sa scuaine cheana féin le híoslódáil.", - "Model {{modelId}} not found": "Níor aimsíodh an tsamhail {{modelId}}", "Model {{modelName}} deleted successfully": "Scriosadh an tsamhail {{modelName}} go rathúil", "Model {{modelName}} is not vision capable": "Níl samhail {{modelName}} in ann amharc", "Model {{name}} is now {{status}}": "Tá samhail {{name}} {{status}} anois", @@ -1752,8 +1772,11 @@ "New Webhook": "Gréasáin Nua", "new-channel": "nua-chainéil", "Next message": "An chéad teachtaireacht eile", + "Next month": "", "Next page": "", "Next run": "An chéad rith eile", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Gan aon deontais rochtana. Príobháideach duitse.", "No actions found": "", "No activity data": "Gan aon sonraí gníomhaíochta", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "Níl aon chomhaid sa bhunachar eolais seo.", "No files yet. Upload files or run Python code to create them.": "Gan aon chomhaid fós. Uaslódáil comhaid nó rith cód Python chun iad a chruthú.", "No filters found": "", + "No folders": "", "No functions found": "Níor aimsíodh aon fheidhmeanna", "No groups found": "Níor aimsíodh aon ghrúpaí", "No history available": "Níl aon stair ar fáil", @@ -1825,6 +1849,7 @@ "No tools accessible": "Gan aon uirlisí inrochtana", "No tools found": "Níor aimsíodh aon uirlisí", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Níor aimsíodh aon úsáideoirí.", "No valves": "Gan comhlaí", "No valves to update": "Gan comhlaí le nuashonrú", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Úps! Tá comhaid fós á n-uaslódáil. Fan go mbeidh an uaslódáil críochnaithe.", "Oops! There was an error in the previous response.": "Úps! Bhí earráid sa fhreagra roimhe seo.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Tá modh gan tacaíocht á úsáid agat (tosaigh amháin). Freastal ar an WebUI ón gcúltaca le do thoil.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Ábhar Forleagan Úsáideora atá ar Feitheamh", "Pending User Overlay Title": "Teideal Forleagan Úsáideora atá ar Feitheamh", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Cead diúltaithe nuair a bhíonn rochtain agat", "Permission denied when accessing microphone": "Cead diúltaithe agus tú ag rochtain ar", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Aitheantas Réimír", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Úsáidtear Aitheantas Réimír chun coinbhleachtaí le naisc eile a sheachaint trí réimír a chur le haitheantas na samhla - fág folamh le díchumasú", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Cosc a chur ar Chruthú Comhad", "Preview": "Réamhamharc", @@ -2043,7 +2071,10 @@ "Previous 30 days": "30 lá roimhe seo", "Previous 7 days": "7 lá roimhe seo", "Previous message": "Teachtaireacht roimhe seo", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Príobháideach", "Private conversation between selected users": "Comhrá príobháideach idir úsáideoirí roghnaithe", "Production version updated": "Leagan táirgeachta nuashonraithe", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Athshocraigh Stóráil/Eolas Veicteoir", "Reset view": "Athshocraigh amharc", "Response": "Freagra", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Ní féidir fógraí freagartha a ghníomhachtú toisc gur diúltaíodh ceadanna an tsuímh Ghréasáin. Tabhair cuairt ar do shocruithe brabhsálaí chun an rochtain riachtanach a dheonú.", "Response Splitting": "", "Response Watermark": "Comhartha Uisce Freagartha", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Toradh", "RESULT": "TORADH", + "Retained Messages": "", "Retrieval": "Aisghabháil", "Retrieval Query Generation": "Aisghabháil Giniúint Ceist", "Retrieved {{count}} sources": "Aisghafa {{count}} foinsí", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "Ní mór don am sceidealaithe a bheith sa todhchaí", "Scopes": "", "Scroll On Branch Change": "Scrollaigh ar Athrú Brainse", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Scrollaigh go Barr", "Search": "Cuardaigh", @@ -2245,6 +2279,7 @@ "Search Files": "Cuardaigh Comhaid", "Search filters": "", "Search Filters": "Scagairí Cuardaigh", + "Search folders": "", "search for archived chats": "cuardach le haghaidh comhráite gcartlann", "search for folders": "cuardach le haghaidh fillteáin", "search for pinned chats": "cuardach le haghaidh comhráite pinn", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "Samhail roghnaithe: {{modelName}}", "Selected model(s) do not support image inputs": "Ní thacaíonn an/na samhlacha roghnaithe le hionchuir íomhá", + "Selected models define incompatible Chat Variables.": "", "semantic": "séimeantach", "Send": "Seol", "Send a Message": "Seol Teachtaireacht", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "Comhroinnt Scileanna don Phobal", "Skills Sharing": "Comhroinnt Scileanna", "Skip Cache": "Seachain an Taisce", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Chuaigh rud éigin mícheart :/", "Sonar": "Sónar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Céimeanna", "Stop": "Stad", + "Stop camera": "", "Stop Download": "Stop an Íoslódáil", "Stop Generating": "Stop a Ghiniúint", "Stop Sequence": "Stop Seicheamh", @@ -2516,6 +2554,7 @@ "Support": "Tacaíocht", "Support this plugin:": "Tacaigh leis an mbreiseán seo:", "Supported MIME Types": "Cineálacha MIME a Tacaítear leo", + "Switch camera": "", "Switch to JSON editor": "Athraigh go heagarthóir JSON", "Switch to visual editor": "Athraigh go dtí an t-eagarthóir amhairc", "Sync": "Sioncrónaigh", @@ -2714,6 +2753,7 @@ "Unmute": "Díbhalbhaigh", "Unpin": "Díbhoráin", "Unpin from Sidebar": "Díbhoráin ón mBarra Taoibh", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Díroinn Comhrá", @@ -2721,6 +2761,7 @@ "Untagged": "Gan chlib", "Untitled": "Gan Teideal", "Update": "Nuashonraigh", + "Update All Models": "", "Update and Copy Link": "Nuashonraigh agus Cóipeáil Nasc", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "úsáideoir", @@ -2792,6 +2834,7 @@ "User Preview": "Réamhamharc Úsáideora", "User ratings (thumbs up/down)": "Rátálacha úsáideoirí (ordóg suas/síos)", "User Status": "Stádas Úsáideora", + "User Variables": "", "User Webhooks": "Crúcaí Gréasáin Úsáideoir", "Username": "Ainm Úsáideora", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Comhlaí", "Valves updated": "Comhlaí dáta", "Valves updated successfully": "Comhlaí nuashonraíodh", "variable": "athraitheach", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Fíoraigh Ceangal", "Verify SSL Certificate": "Fíoraigh Deimhniú SSL", diff --git a/src/lib/i18n/locales/it-IT/translation.json b/src/lib/i18n/locales/it-IT/translation.json index d0d92c7cde..3509da9b3b 100644 --- a/src/lib/i18n/locales/it-IT/translation.json +++ b/src/lib/i18n/locales/it-IT/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Aggiungi utente", "Add User Group": "Aggiungi gruppo utente", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Consenti posizione utente", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "e crea un nuovo link condiviso.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL base per API", "API Key": "Chiave API", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "Permessi chat", "Chat Tags Auto-Generation": "Generazione automatica dei tag chat", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chat", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Controlla di nuovo", "Check for updates": "Controlla aggiornamenti", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Scegli un modello prima di salvare...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Cancella memoria", "Clear Memory": "Cancella memoria", @@ -571,6 +580,7 @@ "Confirm": "Conferma", "Confirm Password": "Conferma password", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Conferma la tua azione", "Confirm your new password": "Conferma la tua nuova password", "Confirm Your Password": "", @@ -727,6 +737,7 @@ "Default to ALL": "Predefinito su TUTTI", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Predefinito per il recupero segmentato per un'estrazione di contenuti mirata e pertinente, questo è raccomandato per la maggior parte dei casi.", + "Default Upload Mode": "", "Default User Role": "Ruolo utente predefinito", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Rileva artefatti automaticamente", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Detta", "Didn't fully follow instructions": "Non ha seguito completamente le istruzioni", "Direct": "Diretto", @@ -846,6 +858,7 @@ "Download as SVG": "Scarica come SVG", "Download canceled": "Scaricamento annullato", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Modifica Utente", "Edit User Group": "Modifica Gruppo Utente", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Abilitato", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "URL Endpoint", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Impossibile salvare le connessioni", "Failed to save conversation": "Impossibile salvare la conversazione", "Failed to save models configuration": "Impossibile salvare la configurazione dei modelli", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Follow up", "Follow Up Generation": "Generazione follow up", "Follow Up Generation Prompt": "Generazione prompt follow up", @@ -1299,6 +1316,7 @@ "Generate an image": "Genera un'immagine", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Mantieni nella barra laterale", "Key": "Chiave", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Conoscenza", "Knowledge Access": "Accesso alla conoscenza", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "In ascolto...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Gli LLM possono commettere errori. Verifica le informazioni importanti.", "Loaded": "", "Loader": "Caricatore", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marzo", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Modello", "Model '{{modelName}}' has been successfully downloaded.": "Il modello '{{modelName}}' è stato scaricato con successo.", "Model '{{modelTag}}' is already in queue for downloading.": "Il modello '{{modelTag}}' è già in coda per il download.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Il modello {{modelName}} non è in grado di vedere", "Model {{name}} is now {{status}}": "Il modello {{name}} è ora {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "nuovo-canale", "Next message": "Messaggio successivo", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Nessun utente trovato.", "No valves": "", "No valves to update": "Nessuna valvola da aggiornare", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ops! Ci sono file ancora in fase di caricamento. Si prega di attendere il completamento del caricamento.", "Oops! There was an error in the previous response.": "Ops! Si è verificato un errore nella risposta precedente.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ops! Stai utilizzando un metodo non supportato (solo frontend). Si prega di servire la WebUI dal backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Contenuto utente in attesa", "Pending User Overlay Title": "Titolo utente in attesa", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Autorizzazione negata durante l'accesso ai dispositivi multimediali", "Permission denied when accessing microphone": "Autorizzazione negata durante l'accesso al microfono", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID prefisso", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "L'ID prefisso viene utilizzato per evitare conflitti con altre connessioni aggiungendo un prefisso agli ID dei modelli - lasciare vuoto per disabilitare", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Anteprima", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Ultimi 30 giorni", "Previous 7 days": "Ultimi 7 giorni", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privato", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Ripristina Archiviazione Vettoriale/Conoscenza", "Reset view": "Ripristina visualizzazione", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Le notifiche di risposta non possono essere attivate poiché i permessi del sito web sono stati negati. Si prega di visitare le impostazioni del browser per concedere l'accesso necessario.", "Response Splitting": "", "Response Watermark": "Watermark della richiesta", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Risultato", "RESULT": "Risultato", + "Retained Messages": "", "Retrieval": "Recupero ricordo", "Retrieval Query Generation": "Generazione di query di recupero ricordo", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Scorri al cambio di branch", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Cerca", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Cerca filtri", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "I modelli selezionati non supportano l'input di immagini", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Invia", "Send a Message": "Invia un messaggio", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Salta cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Arresta", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Sequenza di arresto", @@ -2530,6 +2568,7 @@ "Support": "Supporto", "Support this plugin:": "Supporta questo plugin:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "Rimuovi fissato", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "Non taggato", "Untitled": "Senza titolo", "Update": "Aggiorna", + "Update All Models": "", "Update and Copy Link": "Aggiorna e Copia Link", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "utente", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Webhook Utente", "Username": "Nome Utente", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valvole", "Valves updated": "Valvole aggiornate", "Valves updated successfully": "Valvole aggiornate con successo", "variable": "variabile", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Verifica connessione", "Verify SSL Certificate": "Verifica certificato SSL", diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json index 3e711966e9..6f6cc2a005 100644 --- a/src/lib/i18n/locales/ja-JP/translation.json +++ b/src/lib/i18n/locales/ja-JP/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "", "Add User": "ユーザーを追加", "Add User Group": "ユーザーグループを追加", + "Add User Variable": "", "Add webhook": "ウェブフックを追加", "Add webpage": "ウェブページを追加", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -183,6 +184,7 @@ "Allow User Location": "ユーザーロケーションの許可", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "そして、新しい共有リンクを作成します。", "Android": "アンドロイド", "Anyone": "全員", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API ベース URL", "API Key": "API キー", @@ -281,6 +284,7 @@ "At time of event": "", "Attach File From Knowledge": "ナレッジからファイルを添付", "Attach Files": "ファイルを追加", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "ナレッジを追加", "Attach Notes": "ノートを追加", "Attach Webpage": "ウェブページを追加", @@ -423,8 +427,11 @@ "Chat Permissions": "チャットの許可", "Chat Tags Auto-Generation": "チャットタグの自動生成", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "チャット", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "再確認", "Check for updates": "アップデートを確認", @@ -432,6 +439,7 @@ "Choose a model before saving...": "保存する前にモデルを選択してください...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "メモリをクリア", "Clear Memory": "メモリをクリア", @@ -555,6 +564,7 @@ "Confirm": "確認", "Confirm Password": "パスワードの確認", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "操作の確認", "Confirm your new password": "新しいパスワードの確認", "Confirm Your Password": "パスワードの確認", @@ -711,6 +721,7 @@ "Default to ALL": "標準ではALL", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "デフォルトではセグメント化された検索を使用して、焦点を絞った関連性の高いコンテンツ抽出を行います。これはほとんどの場合に推奨されます。", + "Default Upload Mode": "", "Default User Role": "デフォルトのユーザー役割", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "", "Detect Artifacts Automatically": "自動的にアーティファクトを検出", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "音声入力", "Didn't fully follow instructions": "指示に完全に従わなかった", "Direct": "直接", @@ -830,6 +842,7 @@ "Download as SVG": "SVGとしてダウンロード", "Download canceled": "ダウンロードをキャンセルしました", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "", "Edit User": "ユーザーを編集", "Edit User Group": "ユーザーグループを編集", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -910,6 +924,7 @@ "Enable Web Search": "ウェブ検索を有効にする", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "有効", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "エンドポイントURL", @@ -1165,6 +1180,7 @@ "Failed to remove member": "メンバーを退会させることに失敗しました", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "接続の保存に失敗しました。", "Failed to save conversation": "会話の保存に失敗しました。", "Failed to save models configuration": "モデルの設定の保存に失敗しました。", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "フォルダの更新に成功しました。", "Folders": "フォルダー", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "関連質問", "Follow Up Generation": "関連質問の生成", "Follow Up Generation Prompt": "関連質問の生成プロンプト", @@ -1279,6 +1296,7 @@ "Generate an image": "画像を生成", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "メッセージペアを生成", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "サイドバーに残す", "Key": "キー", "Key is required": "キーは必須です", + "key_name": "", "Keyboard": "", "Knowledge": "ナレッジベース", "Knowledge Access": "ナレッジアクセス", @@ -1530,9 +1549,9 @@ "List": "リスト", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "聞いています...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM は間違いを犯す可能性があります。重要な情報を検証してください。", "Loaded": "", "Loader": "ローダー", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "3月", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "マークダウン", "Markdown Header Text Splitter": "", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "モデル", "Model '{{modelName}}' has been successfully downloaded.": "モデル '{{modelName}}' が正常にダウンロードされました。", "Model '{{modelTag}}' is already in queue for downloading.": "モデル '{{modelTag}}' はすでにダウンロード待機中です。", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "モデル {{modelName}} は視覚に対応していません", "Model {{name}} is now {{status}}": "モデル {{name}} は {{status}} になりました。", @@ -1742,8 +1762,11 @@ "New Webhook": "", "new-channel": "新しいチャンネル", "Next message": "次のメッセージ", + "Next month": "", "Next page": "", "Next run": "次回実行", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "アクセス権は付与されていません。あなただけが利用できます。", "No actions found": "", "No activity data": "", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "functionsが見つかりません", "No groups found": "グループが見つかりません", "No history available": "", @@ -1815,6 +1839,7 @@ "No tools accessible": "", "No tools found": "ツールが見つかりません", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "ユーザーが見つかりません。", "No valves": "バルブがありません", "No valves to update": "更新するバルブがありません", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "おっと! アップロードが完了するまで待ってください。", "Oops! There was an error in the previous response.": "おっと! 前の応答にエラーがありました。", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "おっと! サポートされていない方法 (フロントエンドのみ) を使用しています。バックエンドから WebUI を提供してください。", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "保留中のユーザー情報オーバーレイの内容", "Pending User Overlay Title": "保留中のユーザー情報オーバーレイのタイトル", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "メディアデバイスへのアクセス時に権限が拒否されました", "Permission denied when accessing microphone": "マイクへのアクセス時に権限が拒否されました", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID はモデル ID に接頭辞を追加することで、他の接続との競合を避けるために使用されます - 空の場合は無効にします", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "ファイル作成を防止", "Preview": "プレビュー", @@ -2033,7 +2061,10 @@ "Previous 30 days": "過去30日間", "Previous 7 days": "過去7日間", "Previous message": "前のメッセージ", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "プライベート", "Private conversation between selected users": "", "Production version updated": "", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "ベクターストレージとナレッジベースをリセット", "Reset view": "表示をリセット", "Response": "応答", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "ウェブサイトの許可が拒否されたため、応答の通知をアクティブ化できません。必要なアクセスを許可するためにブラウザの設定を確認してください。", "Response Splitting": "", "Response Watermark": "応答のウォーターマーク", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "結果", "RESULT": "結果", + "Retained Messages": "", "Retrieval": "検索", "Retrieval Query Generation": "検索クエリ生成", "Retrieved {{count}} sources": "{{count}} 件のソースを取得", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "ブランチ変更時にスクロール", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "検索", @@ -2232,6 +2266,7 @@ "Search Files": "ファイルの検索", "Search filters": "", "Search Filters": "フィルターの検索", + "Search folders": "", "search for archived chats": "アーカイブされたチャットを検索", "search for folders": "フォルダを検索", "search for pinned chats": "ピン留めされたチャットを検索", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "一部のモデルは画像入力をサポートしていません", + "Selected models define incompatible Chat Variables.": "", "semantic": "意味的", "Send": "送信", "Send a Message": "メッセージを送信", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "Skillの公開共有", "Skills Sharing": "Skillの共有", "Skip Cache": "キャッシュをスキップする", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "何らかの問題が発生しました", "Sonar": "", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "停止", + "Stop camera": "", "Stop Download": "ダウンロードを停止", "Stop Generating": "生成を停止", "Stop Sequence": "ストップシーケンス", @@ -2502,6 +2540,7 @@ "Support": "サポート", "Support this plugin:": "このプラグインを支援する:", "Supported MIME Types": "対応するMIMEタイプ", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2700,6 +2739,7 @@ "Unmute": "ミュート解除", "Unpin": "ピン留め解除", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2707,6 +2747,7 @@ "Untagged": "タグなし", "Untitled": "タイトルなし", "Update": "更新", + "Update All Models": "", "Update and Copy Link": "リンクの更新とコピー", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "ウェブ検索を使用しますか?", "user": "ユーザー", @@ -2778,6 +2820,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "ユーザーステータス", + "User Variables": "", "User Webhooks": "ユーザWebhook", "Username": "ユーザー名", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "バルブ", "Valves updated": "バルブが更新されました", "Valves updated successfully": "バルブが正常に更新されました", "variable": "変数", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "接続を確認", "Verify SSL Certificate": "SSL証明書を確認", diff --git a/src/lib/i18n/locales/ka-GE/translation.json b/src/lib/i18n/locales/ka-GE/translation.json index 85c9b553e5..f206a01f72 100644 --- a/src/lib/i18n/locales/ka-GE/translation.json +++ b/src/lib/i18n/locales/ka-GE/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "მომხმარებლის დამატება", "Add User Group": "მომხმარებლის ჯგუფის დამატება", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "მომხმარებლის მდებარეობის დაშვება", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "და ახალი გაზიარებული ბმულის შექმნა.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API-ის საბაზისო URL", "API Key": "API გასაღები", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "ცოდნის მიმაგრება", "Attach Notes": "შენიშვნების მიმაგრება", "Attach Webpage": "ვებგვერდის მიმაგრება", @@ -430,8 +434,11 @@ "Chat Permissions": "ჩატის ნებართვები", "Chat Tags Auto-Generation": "ჩატის ჭდეების ავტოგენერაცია", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "საუბრები", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "თავიდან შემოწმება", "Check for updates": "განახლებების შემოწმება", @@ -439,6 +446,7 @@ "Choose a model before saving...": "აირჩიეთ მოდელი შენახვამდე...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "მეხსიერების გასუფთავება", "Clear Memory": "მეხსიერების გასუფთავება", @@ -563,6 +572,7 @@ "Confirm": "დადასტურება", "Confirm Password": "გაიმეორეთ პაროლი", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "დაადასტურეთ თქვენი ქმედება", "Confirm your new password": "დაადასტურეთ თქვენი ახალი პაროლი", "Confirm Your Password": "დაადასტურეთ თქვენი პაროლი", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "მომხმარებლის ნაგულისხმევი როლი", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "კარნახი", "Didn't fully follow instructions": "ინსტრუქციებს სრულად არ მივყევი", "Direct": "პირდაპირი", @@ -838,6 +850,7 @@ "Download as SVG": "გადმოწერა SVG-ის სახით", "Download canceled": "გადმოწერა გაუქმდა", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "მომხმარებლის ჩასწორება", "Edit User Group": "მომხმარებლის ჯგუფის ჩასწორება", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "ჩასწორებულია", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "ჩართულია", + "End call": "", "End Tag": "საბოლოო ჭდე", "Endpoint": "", "Endpoint URL": "ბოლოწერტილის URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "დიაგრამის რენდერი ჩავარდა", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "კავშირების შენახვა ჩავარდა", "Failed to save conversation": "საუბრის შენახვა ვერ მოხერხდა", "Failed to save models configuration": "მოდელების კონფიგურაციის შენახვა ჩავარდა", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "საქაღალდე წარმატებით განახლდა", "Folders": "საქაღალდეები", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "მიდევნება", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "გამოსახულების გენერაცია", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "დატოვება გვერდით პანელზე", "Key": "გასაღები", "Key is required": "გასაღები აუცილებელია", + "key_name": "", "Keyboard": "", "Knowledge": "ცოდნა", "Knowledge Access": "წვდომა ცოდნასთან", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "ვისმენ...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM-ებმა, შეიძლება, შეცდომები დაუშვან. გადაამოწმეთ მნიშვნელოვანი ინფორმაცია.", "Loaded": "", "Loader": "ჩამტვირთავი", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "მარტი", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "მოდელი", "Model '{{modelName}}' has been successfully downloaded.": "მოდელის „{{modelName}}“ გადმოწერა წარმატებით დასრულდა.", "Model '{{modelTag}}' is already in queue for downloading.": "მოდელი „{{modelTag}}“ უკვე გადმოწერის რიგშია.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} is not vision capable", "Model {{name}} is now {{status}}": "Model {{name}} is now {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "new-channel", "Next message": "შემდეგი შეტყობინება", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "ფუნქციები აღმოჩენილი არაა", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "ხელსაწყოები აღმოჩენილი არაა", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "მომხმარებლები აღმოჩენილი არაა.", "No valves": "ონკანები აღმოჩენილი არაა", "No valves to update": "გასაახლებელი ონკანების გარეშე", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "ვაი! იყენებთ მხარდაუჭერელ მეთოდს (მხოლოდ წინაბოლო). შედით WebUI-ზე უკანაბოლოდან.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "პრეფიქსის ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "მინიატურა", @@ -2043,7 +2071,10 @@ "Previous 30 days": "წინა 30 დღე", "Previous 7 days": "წინა 7 დღე", "Previous message": "წინა შეტყობინება", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "პირადი", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "ხედის ჩამოყრა", "Response": "პასუხი", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "შედეგი", "RESULT": "შედეგი", + "Retained Messages": "", "Retrieval": "მიღება", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "ძებნა", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "ფილტრების ძებნა", + "Search folders": "", "search for archived chats": "დაარქივებული ჩატების ძებნა", "search for folders": "საქაღალდეების ძებნა", "search for pinned chats": "ამაგრებული ჩატების ძებნა", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "მონიშნულ მოდელებს გამოსახულების შეყვანის მხარდაჭერა არ გააჩნიათ", + "Selected models define incompatible Chat Variables.": "", "semantic": "სემანტიკური", "Send": "გაგზავნა", "Send a Message": "შეტყობინების გაგზავნა", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "კეშის გამოტოვება", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "რაღაც ცუდადაა :/", "Sonar": "სონარი", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "გაჩერება", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "შეჩერების მიმდევრობა", @@ -2516,6 +2554,7 @@ "Support": "მხარდაჭერა", "Support this plugin:": "დაუჭირეთ მხარი ამ დამატებას:", "Supported MIME Types": "მხარდაჭერილი MIME ტიპები", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "ჩამოხსნა", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "ჭდის გარეშე", "Untitled": "უსათაურო", "Update": "განახლება", + "Update All Models": "", "Update and Copy Link": "განახლება და ბმულის კოპირება", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "მომხმარებელი", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "ვებჰუკების გამოყენება", "Username": "მომხმარებლის სახელი", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "ონკანები", "Valves updated": "ონკანების განახლდა", "Valves updated successfully": "ონკანები წარმატებით განახლდა", "variable": "ცვლადი", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "კავშირის გადამოწმება", "Verify SSL Certificate": "SSL სერტიფიკატის გადამოწმება", diff --git a/src/lib/i18n/locales/kab-DZ/translation.json b/src/lib/i18n/locales/kab-DZ/translation.json index d34ab94018..603d3b2128 100644 --- a/src/lib/i18n/locales/kab-DZ/translation.json +++ b/src/lib/i18n/locales/kab-DZ/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Rnu aseqdac", "Add User Group": "Rnu agraw n iseqdacen", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Sireg adig n useqdac", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "rnu aseɣwen n beṭṭu amaynut.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Tansa URL n taffa i API", "API Key": "Tasarutt API", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Qqen-as tamessunt", "Attach Notes": "Qqen-as tizmilin", "Attach Webpage": "Qqen-as asebter web", @@ -430,8 +434,11 @@ "Chat Permissions": "Isumar n yidiwenniyen", "Chat Tags Auto-Generation": "Asirew awurman n tebzimin", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Idiwenniyen", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Senqed tikelt nniḍen", "Check for updates": "Nadi ileqman", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Fren tamudemt uqbel ad tsellkeḍ...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Sfeḍ takatut", "Clear Memory": "Sfeḍ takatut", @@ -563,6 +572,7 @@ "Confirm": "Sentem", "Confirm Password": "Sentem awal n uɛeddi", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Sergeg tigawt-a", "Confirm your new password": "Sentem awal-ik·im n uɛeddi amaynut", "Confirm Your Password": "Sentem awal-ik⋅im uffir", @@ -719,6 +729,7 @@ "Default to ALL": "S wudem amezwar i meṛṛa", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Ma nmuqel amek ara nɛawed ad nɛawed ad nɛawed ad nɛawed ad d-nekkes ayen yesɛan azal d wayen icudden ɣer ugbur, ilaq-as i tuget n tegnatin.", + "Default Upload Mode": "", "Default User Role": "Tamlilt n useqdac amezwar", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Zubet", "Didn't fully follow instructions": "Ur yeḍfir ara akk iwellihen", "Direct": "Srid", @@ -838,6 +850,7 @@ "Download as SVG": "Zdem am SVG", "Download canceled": "Ittwasefsex usider", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Ẓreg aseqdac", "Edit User Group": "Ẓreg agraw n iseqdacen", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "yettwaẓreg", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "D urmid", + "End call": "", "End Tag": "Tabzimt n tagara", "Endpoint": "", "Endpoint URL": "URL n wagaz n uzgu", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Yecceḍ uklas n tuqqniwin", "Failed to save conversation": "Yecceḍ uklas n udiwenni", "Failed to save models configuration": "Ur yessaweḍ ara ad d-yessukkes tamudemt n usneftaɣ", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Akaram yettwaleqqem akken iwata", "Folders": "Ikaramen", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Aḍfaṛ", "Follow Up Generation": "Ḍfer asirew", "Follow Up Generation Prompt": "Ḍfer tiwtilin n tsuta", @@ -1289,6 +1306,7 @@ "Generate an image": "Sarew tugna", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Senṭeḍ-it deg ufeggag n yidis", "Key": "Tasarutt", "Key is required": "Tlaq tsarut", + "key_name": "", "Keyboard": "", "Knowledge": "Tamusni", "Knowledge Access": "Anekcum ɣer tmussni", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Yettmaḥsis…", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs yezmer ad yecceḍ. Senqed talɣut yesɛan azal.", "Loaded": "", "Loader": "Asalay", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Meɣres", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Tamudemt", "Model '{{modelName}}' has been successfully downloaded.": "Tettwasider-d tmudemt '{{modelName}}' akken iwata.", "Model '{{modelTag}}' is already in queue for downloading.": "Tamudemt '{{modelTag}}' ha-t-an yakan deg tebdart n usader.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Mudel Isem}} mačči d tamuɣli izemren ad tili", "Model {{name}} is now {{status}}": "Tamudemt {{name}} tura {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "abadu amaynut", "Next message": "Izen uḍfir", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Ulac ifecka yettwafen", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Ulac aqeddac i yettwafen.", "No valves": "Ulac isegganen", "No valves to update": "Ulac isegganen ara yettuleqmen", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "Ayhuh! Teḍra-d tuccḍa deg tririt-nni yezrin.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ayhuh! Aql-ik tesseqdaceḍ tarrayt ur yettwasefraken ara (mazwar kan). Ma ulac aɣilif, mudd-d WebUI seg uɛrur.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "Titre n useqdac nnig wakal", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Ttwagedlent tsirag lawan n unekcum ɣer yibenkan n yimidyaten", "Permission denied when accessing microphone": "Yettwagdel unekcum ɣer usawaḍ", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Asulay ID n uzwir", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Asulay n uzwir yettusexdem i wakken ur d-yettili ara umennuɣ akked tuqqna-nniḍen s tmerna n usewgelhen i yimuhal n tmudemt - eǧǧ-iten d ilmawen i tukksa n tuqqna", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Taskant", @@ -2043,7 +2071,10 @@ "Previous 30 days": "30 n wussan yezrin", "Previous 7 days": "7 n wussan yezrin", "Previous message": "Izen udfir", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Uslig", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "Wennez askan", "Response": "Tiririt", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Ilɣa n tririt ur zmiren ara ad ttwasremden imi ugin ttesriḥat n usmel web. Ttxil-k, rzu ɣef yiɣewwaren-ik n yiminig akken ad tkecmeḍ ɣer wayen ilaqen.", "Response Splitting": "", "Response Watermark": "Ticreḍt tafrawant n tririt", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Agmuḍ", "RESULT": "Agmuḍ", + "Retained Messages": "", "Retrieval": "Anadi", "Retrieval Query Generation": "Asirew n tuttra n RAG", "Retrieved {{count}} sources": "Yufa-d {{count}} n yiɣbula", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Abeddel n Branch", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Anadi", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Imsizedgen n unadi", + "Search folders": "", "search for archived chats": "", "search for folders": "anadi ɣef yikaramen", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Ammud(s) yettwafernen ur yessefrak ara inekcamen n tugniwin yettwafernen", + "Selected models define incompatible Chat Variables.": "", "semantic": "tasnamekt", "Send": "Ceyyeɛ", "Send a Message": "Ceyyeɛ izen", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Ur sseqdac ara tuffirt", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Yella wayen ur neddi ara :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Seḥbes", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Tagzemt n uḥbas", @@ -2516,6 +2554,7 @@ "Support": "Tallalt", "Support this plugin:": "Ɛiwen asiɣzef-a:", "Supported MIME Types": "Anawen MIME ttwasefraken", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Kkes asenteḍ", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Tekkes-as tebzimt", "Untitled": "War azwel", "Update": "Muceḍ", + "Update All Models": "", "Update and Copy Link": "Leqqem aseɣwen", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "aseqdac", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Webhooks n yiseqdacen", "Username": "Isem n useqdac", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Isegganen", "Valves updated": "Isegganen ttwaleqmen", "Valves updated successfully": "Valves ttwaleqmen akken iwata", "variable": "tamattayt", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Senqed tuqqna", "Verify SSL Certificate": "Senqed aselkin SSL", diff --git a/src/lib/i18n/locales/ko-KR/translation.json b/src/lib/i18n/locales/ko-KR/translation.json index 27f8f97ae4..511be6bcc6 100644 --- a/src/lib/i18n/locales/ko-KR/translation.json +++ b/src/lib/i18n/locales/ko-KR/translation.json @@ -111,6 +111,7 @@ "Add to favorites": "즐겨찾기에 추가", "Add User": "사용자 추가", "Add User Group": "사용자 그룹 추가", + "Add User Variable": "", "Add webhook": "", "Add webpage": "웹페이지 추가", "Add your Open Terminal URL and API key in Settings → Integrations.": "설정 → 통합에서 Open Terminal URL과 API 키를 추가하세요.", @@ -184,6 +185,7 @@ "Allow User Location": "사용자 위치 활용 허용", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -217,6 +219,7 @@ "and create a new shared link.": "새로운 공유 링크를 생성합니다.", "Android": "안드로이드", "Anyone": "누구나", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API 기본 URL", "API Key": "API 키", @@ -282,6 +285,7 @@ "At time of event": "이벤트 발생 시", "Attach File From Knowledge": "지식 기반에서 파일 첨부", "Attach Files": "첨부 파일", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "지식 기반 첨부", "Attach Notes": "노트 첨부", "Attach Webpage": "웹페이지 첨부", @@ -424,8 +428,11 @@ "Chat Permissions": "채팅 권한", "Chat Tags Auto-Generation": "채팅 태그 자동생성", "Chat unshared successfully.": "채팅 공유 해제 성공", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "채팅", "Chats": "채팅", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "다시 확인", "Check for updates": "업데이트 확인", @@ -433,6 +440,7 @@ "Choose a model before saving...": "저장하기 전에 모델을 선택하세요...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -466,6 +474,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "메모리 초기화", "Clear Memory": "메모리 지우기", @@ -556,6 +565,7 @@ "Confirm": "확인", "Confirm Password": "비밀번호 확인", "Confirm Prompt from Embed": "임베드에서 확인 프롬프트", + "Confirm recording": "", "Confirm your action": "작업 확인", "Confirm your new password": "새로운 비밀번호를 한 번 더 입력해 주세요", "Confirm Your Password": "비밀번호를 확인해주세요", @@ -712,6 +722,7 @@ "Default to ALL": "기본값: 전체", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "집중적이고 관련성 있는 콘텐츠 추출을 위해 세분화된 검색을 기본으로 하며, 대부분의 경우에 권장됩니다.", + "Default Upload Mode": "", "Default User Role": "기본 사용자 역할", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -760,6 +771,7 @@ "Deselect": "선택 해제", "Detect Artifacts Automatically": "아티팩트 자동 감지", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "마이크 사용", "Didn't fully follow instructions": "완전히 지침을 따르지 않음", "Direct": "직접", @@ -831,6 +843,7 @@ "Download as SVG": "SVG로 다운로드", "Download canceled": "다운로드 취소", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -878,6 +891,7 @@ "Edit Terminal Connection": "터미널 연결 편집", "Edit User": "사용자 편집", "Edit User Group": "사용자 그룹 편집", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "workflow.json 콘텐츠 편집", "edited": "수정됨", @@ -911,6 +925,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "모델이 사용하는 추론 태그를 활성화, 비활성화 또는 사용자 지정할 수 있습니다. \"활성화됨\"은 기본 태그를 사용하고, \"비활성화됨\"은 추론 태그를 끄며, \"사용자 지정\"은 직접 시작 및 종료 태그를 지정할 수 있습니다.", "Enabled": "활성화됨", + "End call": "", "End Tag": "종료 태그", "Endpoint": "", "Endpoint URL": "엔드포인트 URL", @@ -1166,6 +1181,7 @@ "Failed to remove member": "멤버 삭제에 실패했습니다", "Failed to render diagram": "다이어그램을 표시할 수 없습니다", "Failed to render visualization": "시각화에 실패했습니다.", + "Failed to save chat variables": "", "Failed to save connections": "연결 저장 실패", "Failed to save conversation": "대화 저장 실패", "Failed to save models configuration": "모델 구성 저장 실패", @@ -1233,6 +1249,7 @@ "Folder updated successfully": "폴더가 성공적으로 업데이트되었습니다", "Folders": "폴더", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "후속 질문", "Follow Up Generation": "후속 질문 생성", "Follow Up Generation Prompt": "후속 질문 생성 프롬프트", @@ -1280,6 +1297,7 @@ "Generate an image": "이미지 생성", "Generate an image prompt before sending the request.": "", "Generate and edit images": "이미지 생성 및 편집", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "메시지 쌍 생성", "Generate suggested follow-up prompts after responses.": "", @@ -1458,6 +1476,7 @@ "Keep in Sidebar": "사이드바에 유지", "Key": "키", "Key is required": "키가 필요합니다", + "key_name": "", "Keyboard": "", "Knowledge": "지식 기반", "Knowledge Access": "지식 기반 접근", @@ -1531,9 +1550,9 @@ "List": "목록", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "듣는 중...", + "LiteLLM": "", "Live": "실시간", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM에 오류가 있을 수 있습니다. 중요한 정보는 확인이 필요합니다.", "Loaded": "", "Loader": "로더", @@ -1572,6 +1591,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "3월", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "마크다운", "Markdown Header Text Splitter": "마크다운 헤더 텍스트 분할기", "Max background": "", @@ -1644,7 +1665,6 @@ "Model": "모델", "Model '{{modelName}}' has been successfully downloaded.": "모델 '{{modelName}}'이/가 성공적으로 다운로드되었습니다.", "Model '{{modelTag}}' is already in queue for downloading.": "모델 '{{modelTag}}'은/는 이미 다운로드 대기열에 있습니다.", - "Model {{modelId}} not found": "모델 {{modelId}}을/를 찾을 수 없습니다", "Model {{modelName}} deleted successfully": "모델 {{modelName}}이/가 성공적으로 삭제되었습니다", "Model {{modelName}} is not vision capable": "모델 {{modelName}}은/는 비전을 사용할 수 없습니다.", "Model {{name}} is now {{status}}": "모델 {{name}}은/는 이제 {{status}} 상태입니다.", @@ -1743,8 +1763,11 @@ "New Webhook": "새 Webhook", "new-channel": "새 채널", "Next message": "다음 메시지", + "Next month": "", "Next page": "", "Next run": "다음 실행", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "접근 권한이 없습니다. 개인용입니다.", "No actions found": "", "No activity data": "활동 데이터가 없습니다", @@ -1775,6 +1798,7 @@ "No files in this knowledge base.": "이 지식 기반에 파일이 없습니다.", "No files yet. Upload files or run Python code to create them.": "아직 파일이 없습니다. 파일을 업로드하거나 Python 코드를 실행하여 생성하세요.", "No filters found": "", + "No folders": "", "No functions found": "함수를 찾을 수 없습니다", "No groups found": "그룹을 찾을 수 없습니다", "No history available": "사용 기록이 없습니다", @@ -1816,6 +1840,7 @@ "No tools accessible": "", "No tools found": "도구를 찾을 수 없습니다", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "사용자를 찾을 수 없습니다", "No valves": "밸브가 없습니다", "No valves to update": "업데이트 할 밸브가 없습니다", @@ -1887,6 +1912,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "이런! 파일이 계속 업로드중 입니다. 업로드가 완료될 때까지 잠시만 기다려주세요.", "Oops! There was an error in the previous response.": "이런! 이전 응답에 에러가 있었던 것 같습니다.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "이런! 지원되지 않는 방식(프론트엔드만)을 사용하고 계십니다. 백엔드에서 WebUI를 제공해주세요.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1964,6 +1990,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "대기 중인 사용자 오버레이 내용", "Pending User Overlay Title": "대기 중인 사용자 오버레이 제목", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "미디어 장치 접근 권한이 거부되었습니다.", "Permission denied when accessing microphone": "마이크 접근 권한이 거부되었습니다.", @@ -2027,6 +2054,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID는 모델 ID에 접두사를 추가하여 다른 연결과의 충돌을 방지하는 데 사용됩니다. - 비활성화하려면 비워 둡니다.", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "파일 생성 방지", "Preview": "미리보기", @@ -2034,7 +2062,10 @@ "Previous 30 days": "이전 30일", "Previous 7 days": "이전 7일", "Previous message": "이전 메시지", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "비공개", "Private conversation between selected users": "선택한 사용자 간의 비공개 대화", "Production version updated": " production 버전이 업데이트되었습니다.", @@ -2166,6 +2197,7 @@ "Reset Vector Storage/Knowledge": "벡터 저장 공간/지식 기반 초기화", "Reset view": "보기 초기화", "Response": "응답", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "웹사이트 권한이 거부되어 응답 알림을 활성화할 수 없습니다. 필요한 접근 권한을 부여하려면 브라우저 설정을 확인해 주세요.", "Response Splitting": "", "Response Watermark": "응답 워터마크", @@ -2174,6 +2206,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "결과", "RESULT": "결과", + "Retained Messages": "", "Retrieval": "검색", "Retrieval Query Generation": "검색 쿼리 생성", "Retrieved {{count}} sources": "{{count}}개의 소스 검색됨", @@ -2218,6 +2251,7 @@ "Scheduled time must be in the future": "예약 시간은 미래여야 합니다", "Scopes": "", "Scroll On Branch Change": "브랜치 변경 시 스크롤", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "검색", @@ -2234,6 +2268,7 @@ "Search Files": "파일 검색", "Search filters": "", "Search Filters": "필터 검색", + "Search folders": "", "search for archived chats": "보관된 채팅 검색", "search for folders": "폴더 검색", "search for pinned chats": "고정된 채팅 검색", @@ -2319,6 +2354,7 @@ "Selected": "", "Selected model: {{modelName}}": "선택된 모델: {{modelName}}", "Selected model(s) do not support image inputs": "선택한 모델은 이미지 입력을 지원하지 않습니다.", + "Selected models define incompatible Chat Variables.": "", "semantic": "의미적", "Send": "보내기", "Send a Message": "메시지 보내기", @@ -2439,6 +2475,7 @@ "Skills Public Sharing": "스킬 공개 공유", "Skills Sharing": "스킬 공유", "Skip Cache": "캐시 무시", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "무언가 잘못 되었습니다 :/", "Sonar": "Sonar", @@ -2474,6 +2511,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "단계", "Stop": "정지", + "Stop camera": "", "Stop Download": "다운로드 중지", "Stop Generating": "생성 중지", "Stop Sequence": "중지 시퀀스", @@ -2505,6 +2543,7 @@ "Support": "지원", "Support this plugin:": "플러그인 지원", "Supported MIME Types": "지원하는 MIME 타입", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "동기화", @@ -2703,6 +2742,7 @@ "Unmute": "", "Unpin": "고정 해제", "Unpin from Sidebar": "사이드바 고정 해제", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "채팅 공유 해제", @@ -2710,6 +2750,7 @@ "Untagged": "태그 해제", "Untitled": "제목 없음", "Update": "업데이트", + "Update All Models": "", "Update and Copy Link": "링크 업데이트 및 복사", "Update Email": "", "Update embedding model": "", @@ -2767,6 +2808,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "사용자", @@ -2781,6 +2823,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "사용자 평가 (좋아요/싫어요)", "User Status": "사용자 상태", + "User Variables": "", "User Webhooks": "사용자 웹훅", "Username": "사용자 이름", "Username Claim": "", @@ -2795,10 +2838,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "밸브", "Valves updated": "밸브 업데이트됨", "Valves updated successfully": "성공적으로 밸브가 업데이트되었습니다", "variable": "변수", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "연결 확인", "Verify SSL Certificate": "SSL 인증서 확인", diff --git a/src/lib/i18n/locales/languages.json b/src/lib/i18n/locales/languages.json index 1e891905ab..b2279d6489 100644 --- a/src/lib/i18n/locales/languages.json +++ b/src/lib/i18n/locales/languages.json @@ -184,9 +184,9 @@ "title": "Slovak (Slovenčina)" }, { - "code": "sl-SI", - "title": "Slovenian (Slovenščina)" - }, + "code": "sl-SI", + "title": "Slovenian (Slovenščina)" + }, { "code": "es-ES", "title": "Spanish (Español)" diff --git a/src/lib/i18n/locales/lt-LT/translation.json b/src/lib/i18n/locales/lt-LT/translation.json index 34da12245d..fb377f0577 100644 --- a/src/lib/i18n/locales/lt-LT/translation.json +++ b/src/lib/i18n/locales/lt-LT/translation.json @@ -131,6 +131,7 @@ "Add to favorites": "", "Add User": "Pridėti naudotoją", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -204,6 +205,7 @@ "Allow User Location": "Leisti naudotojo vietos matymą", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -237,6 +239,7 @@ "and create a new shared link.": "sukurti naują dalinimosi nuorodą", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API basės nuoroda", "API Key": "API raktas", @@ -302,6 +305,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -444,8 +448,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Pokalbiai", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Patikrinti iš naujo", "Check for updates": "Patikrinti atnaujinimus", @@ -453,6 +460,7 @@ "Choose a model before saving...": "Pasirinkite modelį prieš išsaugant...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -486,6 +494,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Ištrinti atmintį", "Clear Memory": "", @@ -579,6 +588,7 @@ "Confirm": "Patvrtinti", "Confirm Password": "Patvirtinkite slaptažodį", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Patvirtinkite veiksmą", "Confirm your new password": "", "Confirm Your Password": "", @@ -735,6 +745,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Numatytoji naudotojo rolė", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -783,6 +794,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Pilnai nesekė instrukcijų", "Direct": "", @@ -854,6 +866,7 @@ "Download as SVG": "", "Download canceled": "Parsisiuntimas atšauktas", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -901,6 +914,7 @@ "Edit Terminal Connection": "", "Edit User": "Redaguoti naudotoją", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -934,6 +948,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Leisti", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1195,6 +1210,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Nepavyko išsaugoti pokalbio", "Failed to save models configuration": "", @@ -1262,6 +1278,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1309,6 +1326,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1487,6 +1505,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Žinios", "Knowledge Access": "", @@ -1560,9 +1579,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Klausoma...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "Dideli kalbos modeliai gali klysti. Patikrinkite atsakymų teisingumą.", "Loaded": "", "Loader": "", @@ -1601,6 +1620,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Kovas", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1673,7 +1694,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' modelis sėkmingai atsisiųstas.", "Model '{{modelTag}}' is already in queue for downloading.": "Modelis '{{modelTag}}' jau atsisiuntimų eilėje.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Modelis {{modelName}} neturi vaizdo gebėjimų", "Model {{name}} is now {{status}}": "Modelis {{name}} dabar {{status}}", @@ -1772,8 +1792,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1804,6 +1827,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1845,6 +1869,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "Nėra atnaujinamų įeičių", @@ -1916,6 +1941,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Naudojate nepalaikomą (front-end) web ui rėžimą. Prašau serviruokite WebUI iš back-end", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1993,6 +2019,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Leidimas atmestas bandant prisijungti prie medijos įrenginių", "Permission denied when accessing microphone": "Mikrofono leidimas atmestas", @@ -2056,6 +2083,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2063,7 +2091,10 @@ "Previous 30 days": "Paskutinės 30 dienų", "Previous 7 days": "Paskutinės 7 dienos", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2201,6 +2232,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Naršyklė neleidžia siųsti pranešimų", "Response Splitting": "", "Response Watermark": "", @@ -2209,6 +2241,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "REZULTATAS", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2255,6 +2288,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Ieškoti", @@ -2271,6 +2305,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2356,6 +2391,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Pasirinkti modeliai nepalaiko vaizdinių užklausų", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Siųsti", "Send a Message": "Siųsti žinutę", @@ -2476,6 +2512,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2513,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Baigt sekvenciją", @@ -2544,6 +2582,7 @@ "Support": "Palaikyti", "Support this plugin:": "Palaikykite šitą modulį", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2742,6 +2781,7 @@ "Unmute": "", "Unpin": "Atsemigti", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2749,6 +2789,7 @@ "Untagged": "", "Untitled": "", "Update": "Atnaujinti", + "Update All Models": "", "Update and Copy Link": "Atnaujinti ir kopijuoti nuorodą", "Update Email": "", "Update embedding model": "", @@ -2806,6 +2847,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "naudotojas", @@ -2820,6 +2862,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2834,10 +2877,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Įeitys", "Valves updated": "Įeitys atnaujintos", "Valves updated successfully": "Įeitys atnaujintos sėkmingai", "variable": "kintamasis", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/lv-LV/translation.json b/src/lib/i18n/locales/lv-LV/translation.json index f8d2a1d58d..30bfcf1284 100644 --- a/src/lib/i18n/locales/lv-LV/translation.json +++ b/src/lib/i18n/locales/lv-LV/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Pievienot lietotāju", "Add User Group": "Pievienot lietotāju grupu", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Pievienot tīmekļa lapu", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Atļaut lietotāja atrašanās vietu", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "un izveidot jaunu kopīgotu saiti.", "Android": "Android", "Anyone": "Jebkurš", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API bāzes URL", "API Key": "API atslēga", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "Pievienot failu no zināšanām", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Pievienot zināšanau bāzi", "Attach Notes": "Pievienot piezīmes", "Attach Webpage": "Pievienot tīmekļa lapu", @@ -437,8 +441,11 @@ "Chat Permissions": "Tērzēšanas atļaujas", "Chat Tags Auto-Generation": "Tērzēšanas tagu automātiska ģenerēšana", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Tērzēšanas", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Pārbaudīt vēlreiz", "Check for updates": "Pārbaudīt atjauninājumus", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Izvēlieties modeli pirms saglabāšanas...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Notīrīt atmiņu", "Clear Memory": "Notīrīt atmiņu", @@ -571,6 +580,7 @@ "Confirm": "Apstiprināt", "Confirm Password": "Apstiprināt paroli", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Apstipriniet savu darbību", "Confirm your new password": "Apstipriniet savu jauno paroli", "Confirm Your Password": "Apstipriniet savu paroli", @@ -727,6 +737,7 @@ "Default to ALL": "Noklusējums ir VISI", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Noklusējums ir segmentēta izgūšana fokusētai un atbilstošai satura ekstrakcijai, tas ir ieteicams vairumā gadījumu.", + "Default Upload Mode": "", "Default User Role": "Noklusējuma lietotāja loma", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Automātiski noteikt artefaktus", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktēt", "Didn't fully follow instructions": "Pilnībā neievēroja norādījumus", "Direct": "Tiešs", @@ -846,6 +858,7 @@ "Download as SVG": "Lejupielādēt kā SVG", "Download canceled": "Lejupielāde atcelta", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Rediģēt lietotāju", "Edit User Group": "Rediģēt lietotāju grupu", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Rediģēt workflow.json saturu", "edited": "rediģēts", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Iespējojiet, atspējojiet vai pielāgojiet modeļa izmantotos spriedumu tagus. \"Iespējots\" izmanto noklusējuma tagus, \"Atspējots\" izslēdz spriedumu tagus, un \"Pielāgots\" ļauj norādīt savus sākuma un beigu tagus.", "Enabled": "Iespējots", + "End call": "", "End Tag": "Beigu tags", "Endpoint": "", "Endpoint URL": "Galapunkta URL", @@ -1185,6 +1200,7 @@ "Failed to remove member": "Neizdevās noņemt dalībnieku", "Failed to render diagram": "Neizdevās attēlot diagrammu", "Failed to render visualization": "Neizdevās attēlot vizualizāciju", + "Failed to save chat variables": "", "Failed to save connections": "Neizdevās saglabāt savienojumus", "Failed to save conversation": "Neizdevās saglabāt sarunu", "Failed to save models configuration": "Neizdevās saglabāt modeļu konfigurāciju", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "Mape veiksmīgi atjaunināta", "Folders": "Mapes", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Turpinājums", "Follow Up Generation": "Turpinājuma ģenerēšana", "Follow Up Generation Prompt": "Turpinājuma ģenerēšanas uzvedne", @@ -1299,6 +1316,7 @@ "Generate an image": "Ģenerēt attēlu", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Ģenerēt ziņojumu pāri", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Saglabāt sānjoslā", "Key": "Atslēga", "Key is required": "Atslēga ir nepieciešama", + "key_name": "", "Keyboard": "", "Knowledge": "Zināšanas", "Knowledge Access": "Zināšanu piekļuve", @@ -1550,9 +1569,9 @@ "List": "Saraksts", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Klausās...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM var kļūdīties. Pārbaudiet svarīgu informāciju.", "Loaded": "", "Loader": "Ielādētājs", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marts", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown galvenes teksta sadalītājs", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Modelis", "Model '{{modelName}}' has been successfully downloaded.": "Modelis '{{modelName}}' ir veiksmīgi lejupielādēts.", "Model '{{modelTag}}' is already in queue for downloading.": "Modelis '{{modelTag}}' jau ir lejupielādes rindā.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Modelis {{modelName}} neatbalsta redzi", "Model {{name}} is now {{status}}": "Modelis {{name}} tagad ir {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "Jauns webhook", "new-channel": "jauns-kanāls", "Next message": "Nākamais ziņojums", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "Nav aktivitātes datu", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "Šajā zināšanu bāzē nav failu.", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "Funkcijas nav atrastas", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "Rīki nav atrasti", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Lietotāji nav atrasti.", "No valves": "Nav vārstu", "No valves to update": "Nav vārstu, ko atjaunināt", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Hmm! Faili joprojām tiek augšupielādēti. Lūdzu, pagaidiet, līdz augšupielāde ir pabeigta.", "Oops! There was an error in the previous response.": "Hmm! Iepriekšējā atbildē bija kļūda.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hmm! Jūs izmantojat neatbalstītu metodi (tikai priekšgals). Lūdzu, apkalpojiet WebUI no aizmugursistēmas.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Gaidošā lietotāja pārklājuma saturs", "Pending User Overlay Title": "Gaidošā lietotāja pārklājuma virsraksts", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Piekļuve multivides ierīcēm liegta", "Permission denied when accessing microphone": "Piekļuve mikrofonam liegta", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefiksa ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefiksa ID tiek izmantots, lai izvairītos no konfliktiem ar citiem savienojumiem, pievienojot prefiksu modeļu ID - atstājiet tukšu, lai atspējotu", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Novērst failu izveidi", "Preview": "Priekšskatījums", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Iepriekšējās 30 dienas", "Previous 7 days": "Iepriekšējās 7 dienas", "Previous message": "Iepriekšējais ziņojums", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privāts", "Private conversation between selected users": "Privāta saruna starp izvēlētajiem lietotājiem", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Atiestatīt vektoru krātuvi/zināšanas", "Reset view": "Atiestatīt skatu", "Response": "Atbilde", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Atbilžu paziņojumus nevar aktivizēt, jo vietnes atļaujas ir liegtas. Lūdzu, apmeklējiet pārlūka iestatījumus, lai piešķirtu nepieciešamo piekļuvi.", "Response Splitting": "", "Response Watermark": "Atbildes ūdenszīme", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Rezultāts", "RESULT": "REZULTĀTS", + "Retained Messages": "", "Retrieval": "Izgūšana", "Retrieval Query Generation": "Izgūšanas vaicājuma ģenerēšana", "Retrieved {{count}} sources": "Izgūti {{count}} avoti", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Ritināt pie zara maiņas", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Meklēt", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Meklēšanas filtri", + "Search folders": "", "search for archived chats": "meklēt arhivētās tērzēšanas", "search for folders": "meklēt mapes", "search for pinned chats": "meklēt piespraustās tērzēšanas", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Izvēlētais(-ie) modelis(-i) neatbalsta attēlu ievades", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantisks", "Send": "Nosūtīt", "Send a Message": "Nosūtīt ziņojumu", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Izlaist kešatmiņu", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Kaut kas nogāja greizi :/", "Sonar": "Sonar", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Soļi", "Stop": "Apturēt", + "Stop camera": "", "Stop Download": "Apturēt lejupielādi", "Stop Generating": "Apturēt ģenerēšanu", "Stop Sequence": "Apstāšanās secība", @@ -2530,6 +2568,7 @@ "Support": "Atbalsts", "Support this plugin:": "Atbalstiet šo spraudni:", "Supported MIME Types": "Atbalstītie MIME tipi", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "Sinhronizēt", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "Atspraust", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "Bez tagiem", "Untitled": "Bez nosaukuma", "Update": "Atjaunināt", + "Update All Models": "", "Update and Copy Link": "Atjaunināt un kopēt saiti", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "lietotājs", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Lietotāju vērtējumi (patīk/nepatīk)", "User Status": "Lietotāja statuss", + "User Variables": "", "User Webhooks": "Lietotāja webhook", "Username": "Lietotājvārds", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Vārsti", "Valves updated": "Vārsti atjaunināti", "Valves updated successfully": "Vārsti veiksmīgi atjaunināti", "variable": "mainīgais", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Pārbaudīt savienojumu", "Verify SSL Certificate": "Pārbaudīt SSL sertifikātu", diff --git a/src/lib/i18n/locales/ms-MY/translation.json b/src/lib/i18n/locales/ms-MY/translation.json index de6f939196..b17872b7e9 100644 --- a/src/lib/i18n/locales/ms-MY/translation.json +++ b/src/lib/i18n/locales/ms-MY/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "Tambah ke kegemaran", "Add User": "Tambah Pengguna", "Add User Group": "Tambah Kumpulan Pengguna", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Tambah halaman web", "Add your Open Terminal URL and API key in Settings → Integrations.": "Tambah URL Open Terminal dan kunci API anda dalam Tetapan → Integrasi.", @@ -183,6 +184,7 @@ "Allow User Location": "Benarkan Lokasi Pengguna", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "dan cipta pautan kongsi baharu", "Android": "Android", "Anyone": "Sesiapa", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Asas API", "API Key": "Kunci API", @@ -281,6 +284,7 @@ "At time of event": "Pada masa acara", "Attach File From Knowledge": "Lampirkan Fail Daripada Pengetahuan", "Attach Files": "Lampirkan Fail", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Lampirkan Pengetahuan", "Attach Notes": "Lampirkan Nota", "Attach Webpage": "Lampirkan Halaman Web", @@ -423,8 +427,11 @@ "Chat Permissions": "Kebenaran Perbualan", "Chat Tags Auto-Generation": "Penjanaan Auto Tag Perbualan", "Chat unshared successfully.": "Perbualan berjaya dinyahkongsi.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "perbualan", "Chats": "Perbualan", + "Chats Open Sharing": "", "Chats Public Sharing": "Perkongsian Awam Perbualan", "Check Again": "Semak Kembali", "Check for updates": "Semak kemas kini", @@ -432,6 +439,7 @@ "Choose a model before saving...": "Pilih model sebelum menyimpan", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Kosongkan ingatan", "Clear Memory": "Padam Ingatan", @@ -555,6 +564,7 @@ "Confirm": "Sahkan", "Confirm Password": "Sahkan kata laluan", "Confirm Prompt from Embed": "Sahkan Arahan daripada Embed", + "Confirm recording": "", "Confirm your action": "Sahkan tindakan anda", "Confirm your new password": "Sahkan kata laluan baharu anda", "Confirm Your Password": "Sahkan Kata Laluan Anda", @@ -711,6 +721,7 @@ "Default to ALL": "Lalai kepada SEMUA", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Lalai kepada pengambilan tersegmen untuk pengekstrakan kandungan yang berfokus dan relevan, ini disyorkan untuk kebanyakan kes.", + "Default Upload Mode": "", "Default User Role": "Peranan Pengguna Lalai", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "Nyahpilih", "Detect Artifacts Automatically": "Kesan Artifak Secara Automatik", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktasi", "Didn't fully follow instructions": "Tidak mengikut arahan sepenuhnya", "Direct": "Langsung", @@ -830,6 +842,7 @@ "Download as SVG": "Muat turun sebagai SVG", "Download canceled": "Muat Turun dibatalkan", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "Edit Sambungan Terminal", "Edit User": "Edit Pengguna", "Edit User Group": "Edit Kumpulan Pengguna", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Edit kandungan workflow.json", "edited": "disunting", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Aktifkan, nyahaktifkan, atau sesuaikan tag penaakulan yang digunakan oleh model. \"Diaktifkan\" menggunakan tag lalai, \"Dinyahaktifkan\" mematikan tag penaakulan, dan \"Tersuai\" membenarkan anda menentukan tag permulaan dan akhir anda sendiri.", "Enabled": "Diaktifkan", + "End call": "", "End Tag": "Tag Akhir", "Endpoint": "", "Endpoint URL": "URL Titik Akhir", @@ -1165,6 +1180,7 @@ "Failed to remove member": "Gagal mengeluarkan ahli", "Failed to render diagram": "Gagal memapar rajah", "Failed to render visualization": "Gagal memapar visualisasi", + "Failed to save chat variables": "", "Failed to save connections": "Gagal menyimpan sambungan", "Failed to save conversation": "Gagal menyimpan perbualan", "Failed to save models configuration": "Gagal menyimpan konfigurasi model", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "Folder berjaya dikemas kini", "Folders": "Folder-folder", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Susulan", "Follow Up Generation": "Penjanaan Susulan", "Follow Up Generation Prompt": "Arahan Penjanaan Susulan", @@ -1279,6 +1296,7 @@ "Generate an image": "Janakan imej", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Janakan dan edit imej", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Janakan Pasangan Mesej", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "Simpan dalam Bar Sisi", "Key": "Kunci", "Key is required": "Kunci diperlukan", + "key_name": "", "Keyboard": "", "Knowledge": "Pengetahuan", "Knowledge Access": "Akses Pengetahuan", @@ -1530,9 +1549,9 @@ "List": "Senarai", "List calendars, search, create, update, and delete calendar events": "Senaraikan kalendar, cari, cipta, kemas kini, dan padamkan acara kalendar", "Listening...": "Mendengar...", + "LiteLLM": "", "Live": "Langsung", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM boleh membuat kesilapan. Sahkan maklumat penting.", "Loaded": "Dimuatkan", "Loader": "Pemuat", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mac", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Pemisah Teks Tajuk Markdown", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{ modelName }}' telah berjaya dimuat turun.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{ modelTag }}' sudah dalam baris gilir untuk dimuat turun.", - "Model {{modelId}} not found": "Model {{modelId}} tidak dijumpai", "Model {{modelName}} deleted successfully": "Model {{modelName}} berjaya dipadam", "Model {{modelName}} is not vision capable": "Model {{ modelName }} tidak mempunyai keupayaan penglihatan", "Model {{name}} is now {{status}}": "Model {{name}} kini {{status}}", @@ -1742,8 +1762,11 @@ "New Webhook": "Webhook Baharu", "new-channel": "saluran-baru", "Next message": "Mesej Seterusnya", + "Next month": "", "Next page": "", "Next run": "Pelaksanaan seterusnya", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Tiada geran akses. Peribadi untuk anda.", "No actions found": "", "No activity data": "Tiada data aktiviti", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "Tiada fail dalam pangkalan pengetahuan ini.", "No files yet. Upload files or run Python code to create them.": "Tiada fail lagi. Muat naik fail atau jalankan kod Python untuk menciptanya.", "No filters found": "", + "No folders": "", "No functions found": "Tiada fungsi ditemui", "No groups found": "Tiada kumpulan ditemui", "No history available": "Tiada sejarah tersedia", @@ -1815,6 +1839,7 @@ "No tools accessible": "", "No tools found": "Tiada alat ditemui", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Tiada pengguna ditemui.", "No valves": "Tiada Valves", "No valves to update": "Tiada Valves untuk dikemas kini", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Aduh! Masih ada fail sedang dimuat naik. Sila tunggu sehingga muatan selesai.", "Oops! There was an error in the previous response.": "Alamak! Ada ralat dalam respons sebelumnya.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Maaf, anda menggunakan kaedah yang tidak disokong (bahagian 'frontend' sahaja). Sila sediakan WebUI daripada 'backend'.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Kandungan Lapisan Pengguna Tertangguh", "Pending User Overlay Title": "Tajuk Lapisan Pengguna Tertangguh", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Tidak mendapat kebenaran apabila cuba mengakses peranti media", "Permission denied when accessing microphone": "Tidak mendapat kebenaran apabila cuba mengakses mikrofon", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID Awalan", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "ID Awalan digunakan untuk mengelakkan konflik dengan sambungan lain dengan menambah awalan pada ID model - biarkan kosong untuk menyahaktifkan", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Cegah Penciptaan Fail", "Preview": "Pratonton", @@ -2033,7 +2061,10 @@ "Previous 30 days": "30 hari sebelumnya", "Previous 7 days": "7 hari sebelumnya", "Previous message": "Mesej sebelumnya", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Peribadi", "Private conversation between selected users": "Perbualan peribadi antara pengguna terpilih", "Production version updated": "Versi pengeluaran dikemas kini", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "Tetapkan Semula Storan Vektor/Pengetahuan", "Reset view": "Tetapkan Semula Paparan", "Response": "Respons", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Pemberitahuan respons tidak boleh diaktifkan kerana kebenaran tapak web tidak diberi. Sila lawati tetapan pelayar web anda untuk memberikan akses yang diperlukan.", "Response Splitting": "", "Response Watermark": "Tera Air Respons", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Hasil", "RESULT": "KEPUTUSAN", + "Retained Messages": "", "Retrieval": "Pengambilan", "Retrieval Query Generation": "Penjanaan Pertanyaan Pengambilan", "Retrieved {{count}} sources": "Mengambil {{count}} sumber", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "Masa dijadualkan mestilah pada masa hadapan", "Scopes": "", "Scroll On Branch Change": "Skrol Semasa Pertukaran Cabang", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Tatal ke Atas", "Search": "Carian", @@ -2232,6 +2266,7 @@ "Search Files": "Cari Fail", "Search filters": "", "Search Filters": "Penapis Carian", + "Search folders": "", "search for archived chats": "cari untuk perbualan yang diarkibkan", "search for folders": "cari untuk folder", "search for pinned chats": "cari untuk perbualan yang disematkan", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "Model terpilih: {{modelName}}", "Selected model(s) do not support image inputs": "Model dipilih tidak menyokong input imej", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantik", "Send": "Hantar", "Send a Message": "Hantar Pesanan", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "Perkongsian Awam Kemahiran", "Skills Sharing": "Perkongsian Kemahiran", "Skip Cache": "Langkau Cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Ada yang salah :/", "Sonar": "Sonar", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Langkah-langkah", "Stop": "Henti", + "Stop camera": "", "Stop Download": "Hentikan Muat Turun", "Stop Generating": "Hentikan Penjanaan", "Stop Sequence": "Jujukan Henti", @@ -2502,6 +2540,7 @@ "Support": "Sokongan", "Support this plugin:": "Sokong plugin ini", "Supported MIME Types": "Jenis MIME yang Disokong", + "Switch camera": "", "Switch to JSON editor": "Tukar ke penyunting JSON", "Switch to visual editor": "Tukar ke penyunting visual", "Sync": "Segerak", @@ -2700,6 +2739,7 @@ "Unmute": "Nyahredam", "Unpin": "Nyahsematkan", "Unpin from Sidebar": "Nyahsemat daripada Bar Sisi", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Batalkan Perkongsian Perbualan", @@ -2707,6 +2747,7 @@ "Untagged": "Tanpa Tag", "Untitled": "Tanpa Tajuk", "Update": "Kemas Kini", + "Update All Models": "", "Update and Copy Link": "Kemas Kini dan Salin Pautan", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "pengguna", @@ -2778,6 +2820,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Penilaian Pengguna (ibu jari naik/turun)", "User Status": "Status Pengguna", + "User Variables": "", "User Webhooks": "Webhook Pengguna", "Username": "Nama Pengguna", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves dikemas kini", "Valves updated successfully": "Valves berjaya dikemas kini", "variable": "pembolehubah", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Sahkan Sambungan", "Verify SSL Certificate": "Sahkan Sijil SSL", diff --git a/src/lib/i18n/locales/nb-NO/translation.json b/src/lib/i18n/locales/nb-NO/translation.json index 81e3929d92..6ce9f7974f 100644 --- a/src/lib/i18n/locales/nb-NO/translation.json +++ b/src/lib/i18n/locales/nb-NO/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Legg til bruker", "Add User Group": "Legg til brukergruppe", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Aktiver stedstjenester", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "og opprett en ny delt lenke.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Absolutt API-URL", "API Key": "API-nøkkel", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Tillatelser for chat", "Chat Tags Auto-Generation": "Auto-generering av chatetiketter", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chatter", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Sjekk på nytt", "Check for updates": "Sjekk for oppdateringer", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Velg en modell før du lagrer ...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Tøm minnet", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "Bekreft", "Confirm Password": "Bekreft passordet", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Bekreft handlingen", "Confirm your new password": "Bekreft det nye passordet ditt", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "Velg ALL som standard", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Standard brukerrolle", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Fulgte ikke instruksjonene fullstendig", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "Last ned som SVG", "Download canceled": "Nedlasting avbrutt", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Rediger bruker", "Edit User Group": "Rediger brukergruppe", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Aktivert", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Kan ikke lagre samtalen", "Failed to save models configuration": "Kan ikke lagre konfigurasjonen av modeller", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "Genrer et bilde", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Nøkkel", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Kunnskap", "Knowledge Access": "Tilgang til kunnskap", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Lytter ...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Språkmodeller kan gjøre feil. Kontroller viktige opplysninger.", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "mars", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Modell", "Model '{{modelName}}' has been successfully downloaded.": "Modellen {{modelName}} er lastet ned.", "Model '{{modelTag}}' is already in queue for downloading.": "Modellen {{modelTag}} er allerede i nedlastingskøen.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Modellen {{modelName}} er ikke egnet til visuelle data", "Model {{name}} is now {{status}}": "Modellen {{name}} er nå {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "ny-kanal", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Finner ingen brukere", "No valves": "", "No valves to update": "Ingen ventiler å oppdatere", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Oi! Det er fortsatt filer som lastes opp. Vent til opplastingen er ferdig.", "Oops! There was an error in the previous response.": "Oi! Det er en feil i det forrige svaret.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oi! Du bruker en ikke-støttet metode (bare frontend). Du må kjøre WebUI fra backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Tilgang avslått ved bruk av medieenheter", "Permission denied when accessing microphone": "Tilgang avslått ved bruk av mikrofonen", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefiks-ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefiks-ID brukes for å unngå konflikter med andre tilkoblinger ved å legge til et prefiks til modell-ID-ene. La det stå tomt for å deaktivere", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Siste 30 dager", "Previous 7 days": "Siste 7 dager", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Tilbakestill Vector-lagring/kunnskap", "Reset view": "Tilbakestill visning", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Svar-varsler kan ikke aktiveres fordi tilgang til nettstedet er nektet. Gå til nettleserinnstillingene dine for å gi den nødvendige tilgangen.", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultat", "RESULT": "Resultat", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "Generering av spørsmål om henting", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Søk", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Søk etter filtre", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Valgte modell(er) støtter ikke bildeinndata", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Send", "Send a Message": "Send en melding", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Stopp", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Stoppsekvens", @@ -2516,6 +2554,7 @@ "Support": "Bidra", "Support this plugin:": "Bidra til denne utvidelsen:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Løsne", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Ikke merket", "Untitled": "", "Update": "Oppdater", + "Update All Models": "", "Update and Copy Link": "Oppdater og kopier lenke", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "bruker", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Brukernavn", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Ventiler", "Valves updated": "Ventiler oppdatert", "Valves updated successfully": "Ventilene er oppdatert", "variable": "variabel", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/nl-NL/translation.json b/src/lib/i18n/locales/nl-NL/translation.json index ae0666b5d5..6cb44cd56b 100644 --- a/src/lib/i18n/locales/nl-NL/translation.json +++ b/src/lib/i18n/locales/nl-NL/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Aan favorieten toevoegen", "Add User": "Voeg gebruiker toe", "Add User Group": "Voeg gebruikersgroep toe", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Webpagina toevoegen", "Add your Open Terminal URL and API key in Settings → Integrations.": "Voeg je Open Terminal-URL en API-sleutel toe in Instellingen -> Integraties.", @@ -190,6 +191,7 @@ "Allow User Location": "Gebruikerslocatie toestaan", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "en maak een nieuwe gedeelde link.", "Android": "Android", "Anyone": "Iedereen", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Base URL", "API Key": "API-sleutel", @@ -288,6 +291,7 @@ "At time of event": "Op het moment van de gebeurtenis", "Attach File From Knowledge": "Bestand uit kennis toevoegen", "Attach Files": "Bestanden toevoegen", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Kennis toevoegen", "Attach Notes": "Notities toevoegen", "Attach Webpage": "Webpagina toevoegen", @@ -430,8 +434,11 @@ "Chat Permissions": "Chattoestemmingen", "Chat Tags Auto-Generation": "Chatlabels automatisch genereren", "Chat unshared successfully.": "Chatdeling succesvol opgeheven.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "chats", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Controleer Opnieuw", "Check for updates": "Controleer op updates", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Kies een model voordat je opslaat...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Geheugen wissen", "Clear Memory": "Geheugen wissen", @@ -563,6 +572,7 @@ "Confirm": "Bevestigen", "Confirm Password": "Bevestig wachtwoord", "Confirm Prompt from Embed": "Prompt uit embed bevestigen", + "Confirm recording": "", "Confirm your action": "Bevestig je actie", "Confirm your new password": "Bevestig je nieuwe wachtwoord", "Confirm Your Password": "Bevestig je wachtwoord", @@ -719,6 +729,7 @@ "Default to ALL": "Standaard op ALL", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Standaard gesegmenteerd ophalen voor gerichte en relevante inhoudsextractie, dit wordt aanbevolen voor de meeste gevallen.", + "Default Upload Mode": "", "Default User Role": "Standaard gebruikersrol", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "Deselecteren", "Detect Artifacts Automatically": "Artefacten automatisch detecteren", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dicteren", "Didn't fully follow instructions": "Heeft niet alle instructies gevolgd", "Direct": "Direct", @@ -838,6 +850,7 @@ "Download as SVG": "Download als SVG", "Download canceled": "Download geannuleerd", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Terminalverbinding bewerken", "Edit User": "Wijzig gebruiker", "Edit User Group": "Bewerk gebruikergroep", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "workflow.json-inhoud bewerken", "edited": "bewerkt", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Schakel de redeneringstags die door het model worden gebruikt in, uit of pas ze aan. \"Ingeschakeld\" gebruikt standaardtags, \"Uitgeschakeld\" zet redeneringstags uit en \"Aangepast\" laat je je eigen begin- en eindtags instellen.", "Enabled": "Ingeschakeld", + "End call": "", "End Tag": "Eindtag", "Endpoint": "", "Endpoint URL": "Endpoint-URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Lid verwijderen mislukt", "Failed to render diagram": "Diagram renderen mislukt", "Failed to render visualization": "Visualisatie renderen mislukt", + "Failed to save chat variables": "", "Failed to save connections": "Verbindingen opslaan mislukt", "Failed to save conversation": "Het is niet gelukt om het gesprek op te slaan", "Failed to save models configuration": "Het is niet gelukt om de modelconfiguratie op te slaan", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Map succesvol bijgewerkt", "Folders": "Mappen", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Vervolg", "Follow Up Generation": "Vervolggeneratie", "Follow Up Generation Prompt": "Prompt voor vervolggeneratie", @@ -1289,6 +1306,7 @@ "Generate an image": "Genereer een afbeelding", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Afbeeldingen genereren en bewerken", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Berichtenpaar genereren", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "In zijbalk houden", "Key": "Sleutel", "Key is required": "Sleutel is vereist", + "key_name": "", "Keyboard": "", "Knowledge": "Kennis", "Knowledge Access": "Kennistoegang", @@ -1540,9 +1559,9 @@ "List": "Lijst", "List calendars, search, create, update, and delete calendar events": "Agenda's weergeven, zoeken, maken, bijwerken en agenda-afspraken verwijderen", "Listening...": "Aan het luisteren...", + "LiteLLM": "", "Live": "Live", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs kunnen fouten maken. Verifieer belangrijke informatie.", "Loaded": "", "Loader": "Lader", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "maart", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown-koptekstsplitser", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' is succesvol gedownload.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' staat al in de wachtrij voor downloaden.", - "Model {{modelId}} not found": "Model {{modelId}} niet gevonden", "Model {{modelName}} deleted successfully": "Model {{modelName}} is succesvol verwijderd", "Model {{modelName}} is not vision capable": "Model {{modelName}} is niet geschikt voor visie", "Model {{name}} is now {{status}}": "Model {{name}} is nu {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "Nieuwe webhook", "new-channel": "nieuw-kanaal", "Next message": "Volgend bericht", + "Next month": "", "Next page": "", "Next run": "Volgende uitvoering", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Geen toegangsrechten. Alleen privé voor jou.", "No actions found": "", "No activity data": "Geen activiteitsgegevens", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "Geen bestanden in deze kennisbank.", "No files yet. Upload files or run Python code to create them.": "Nog geen bestanden. Upload bestanden of voer Python-code uit om ze te maken.", "No filters found": "", + "No folders": "", "No functions found": "Geen functies gevonden", "No groups found": "Geen groepen gevonden", "No history available": "Geen geschiedenis beschikbaar", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Geen tools gevonden", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Geen gebruikers gevonden", "No valves": "Geen kleppen", "No valves to update": "Geen kleppen om bij te werken", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Oeps! Er zijn nog bestanden aan het uploaden. Wacht tot het uploaden voltooid is.", "Oops! There was an error in the previous response.": "Oeps! Er was een fout in de vorige reactie.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oeps! Je gebruikt een niet-ondersteunde methode (alleen frontend). Serveer de WebUI vanuit de backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Inhoud van overlay voor wachtende gebruiker", "Pending User Overlay Title": "Titel van overlay voor wachtende gebruiker", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Toegang geweigerd bij het toegang krijgen tot media-apparaten", "Permission denied when accessing microphone": "Toegang geweigerd bij toegang tot de microfoon", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Voorvoegsel-ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Voorvoegsel-ID wordt gebruikt om conflicten met andere verbindingen te vermijden door een voorvoegsel aan het model-ID toe te voegen - laat leeg om uit te schakelen", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Bestandsaanmaak voorkomen", "Preview": "Voorvertoning", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Afgelopen 30 dagen", "Previous 7 days": "Afgelopen 7 dagen", "Previous message": "Vorige bericht", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privé", "Private conversation between selected users": "Privégesprek tussen geselecteerde gebruikers", "Production version updated": "Productieversie bijgewerkt", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Herstel Vectoropslag/-kennis", "Reset view": "Herstel zicht", "Response": "Antwoord", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Antwoordmeldingen kunnen niet worden geactiveerd omdat de rechten voor de website zijn geweigerd. Ga naar de instellingen van je browser om de benodigde toegang te verlenen.", "Response Splitting": "", "Response Watermark": "Antwoordwatermerk", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultaat", "RESULT": "Resultaat", + "Retained Messages": "", "Retrieval": "Ophalen", "Retrieval Query Generation": "Ophaalqueriegeneratie", "Retrieved {{count}} sources": "{{count}} bronnen opgehaald", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "Ingeplande tijd moet in de toekomst liggen", "Scopes": "", "Scroll On Branch Change": "Scrollen bij wijziging van branch", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Zoeken", @@ -2245,6 +2279,7 @@ "Search Files": "Bestanden zoeken", "Search filters": "", "Search Filters": "Zoek naar filters", + "Search folders": "", "search for archived chats": "zoek naar gearchiveerde chats", "search for folders": "zoek naar mappen", "search for pinned chats": "zoek naar vastgemaakte chats", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "Geselecteerd model: {{modelName}}", "Selected model(s) do not support image inputs": "Geselecteerde modellen ondersteunen geen beeldinvoer", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantisch", "Send": "Verzenden", "Send a Message": "Stuur een bericht", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "Openbaar delen van vaardigheden", "Skills Sharing": "Vaardigheden delen", "Skip Cache": "Cache overslaan", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Er is iets misgegaan :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Stappen", "Stop": "Stop", + "Stop camera": "", "Stop Download": "Download stoppen", "Stop Generating": "Genereren stoppen", "Stop Sequence": "Stopsequentie", @@ -2516,6 +2554,7 @@ "Support": "Ondersteuning", "Support this plugin:": "ondersteun deze plugin", "Supported MIME Types": "Ondersteunde MIME-typen", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "Synchroniseren", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Losmaken", "Unpin from Sidebar": "Losmaken van zijbalk", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Chat delen opheffen", @@ -2721,6 +2761,7 @@ "Untagged": "Ongemarkeerd", "Untitled": "Zonder titel", "Update": "Bijwerken", + "Update All Models": "", "Update and Copy Link": "Bijwerken en kopieer link", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "gebruiker", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Gebruikersbeoordelingen (duim omhoog/omlaag)", "User Status": "Gebruikersstatus", + "User Variables": "", "User Webhooks": "Gebruiker-webhooks", "Username": "Gebruikersnaam", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Kleppen", "Valves updated": "Kleppen bijgewerkt", "Valves updated successfully": "Kleppen succesvol bijgewerkt", "variable": "variabele", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Controleer verbinding", "Verify SSL Certificate": "SSL-certificaat verifiëren", diff --git a/src/lib/i18n/locales/pa-IN/translation.json b/src/lib/i18n/locales/pa-IN/translation.json index 69305747a2..1f60a4a370 100644 --- a/src/lib/i18n/locales/pa-IN/translation.json +++ b/src/lib/i18n/locales/pa-IN/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "ਉਪਭੋਗਤਾ ਸ਼ਾਮਲ ਕਰੋ", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "ਅਤੇ ਇੱਕ ਨਵਾਂ ਸਾਂਝਾ ਲਿੰਕ ਬਣਾਓ।", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API ਬੇਸ URL", "API Key": "API ਕੁੰਜੀ", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "ਗੱਲਾਂ", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "ਮੁੜ ਜਾਂਚ ਕਰੋ", "Check for updates": "ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ", @@ -439,6 +446,7 @@ "Choose a model before saving...": "ਸੰਭਾਲਣ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕ ਮਾਡਲ ਚੁਣੋ...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "ਮੂਲ ਉਪਭੋਗਤਾ ਭੂਮਿਕਾ", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "ਹਦਾਇਤਾਂ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਫਾਲੋ ਨਹੀਂ ਕੀਤਾ", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "ਡਾਊਨਲੋਡ ਰੱਦ ਕੀਤਾ ਗਿਆ", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "ਉਪਭੋਗਤਾ ਸੰਪਾਦਨ ਕਰੋ", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "ਚਾਲੂ", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "ਗੱਲਬਾਤ ਸੰਭਾਲਣ ਵਿੱਚ ਅਸਫਲ", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLMs ਗਲਤੀਆਂ ਕਰ ਸਕਦੇ ਹਨ। ਮਹੱਤਵਪੂਰਨ ਜਾਣਕਾਰੀ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "ਮਾਰਚ", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "", "Model '{{modelName}}' has been successfully downloaded.": "ਮਾਡਲ '{{modelName}}' ਸਫਲਤਾਪੂਰਵਕ ਡਾਊਨਲੋਡ ਕੀਤਾ ਗਿਆ ਹੈ।", "Model '{{modelTag}}' is already in queue for downloading.": "ਮਾਡਲ '{{modelTag}}' ਪਹਿਲਾਂ ਹੀ ਡਾਊਨਲੋਡ ਲਈ ਕਤਾਰ ਵਿੱਚ ਹੈ।", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "ਮਾਡਲ {{modelName}} ਦ੍ਰਿਸ਼ਟੀ ਸਮਰੱਥ ਨਹੀਂ ਹੈ", "Model {{name}} is now {{status}}": "ਮਾਡਲ {{name}} ਹੁਣ {{status}} ਹੈ", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "ਓਹੋ! ਤੁਸੀਂ ਇੱਕ ਅਣਸਮਰਥਿਤ ਢੰਗ ਵਰਤ ਰਹੇ ਹੋ (ਸਿਰਫ਼ ਫਰੰਟਐਂਡ)। ਕਿਰਪਾ ਕਰਕੇ ਵੈਬਯੂਆਈ ਨੂੰ ਬੈਕਐਂਡ ਤੋਂ ਸਰਵ ਕਰੋ।", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "ਪਿਛਲੇ 30 ਦਿਨ", "Previous 7 days": "ਪਿਛਲੇ 7 ਦਿਨ", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "ਨਤੀਜਾ", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "ਖੋਜ", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "ਚੁਣੇ ਗਏ ਮਾਡਲ(ਆਂ) ਚਿੱਤਰ ਇਨਪੁੱਟਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੇ", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "ਭੇਜੋ", "Send a Message": "ਇੱਕ ਸੁਨੇਹਾ ਭੇਜੋ", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "ਰੋਕੋ ਕ੍ਰਮ", @@ -2516,6 +2554,7 @@ "Support": "", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "", + "Update All Models": "", "Update and Copy Link": "ਅੱਪਡੇਟ ਕਰੋ ਅਤੇ ਲਿੰਕ ਕਾਪੀ ਕਰੋ", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "ਉਪਭੋਗਤਾ", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "ਵੈਰੀਏਬਲ", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/pl-PL/translation.json b/src/lib/i18n/locales/pl-PL/translation.json index 1375067dde..c367b7553b 100644 --- a/src/lib/i18n/locales/pl-PL/translation.json +++ b/src/lib/i18n/locales/pl-PL/translation.json @@ -131,6 +131,7 @@ "Add to favorites": "Dodaj do ulubionych", "Add User": "Dodaj użytkownika", "Add User Group": "Dodaj grupę użytkowników", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Dodaj stronę WWW", "Add your Open Terminal URL and API key in Settings → Integrations.": "Dodaj adres URL Open Terminal i klucz API w Ustawienia → Integracje.", @@ -204,6 +205,7 @@ "Allow User Location": "Zezwól na lokalizację użytkownika", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -237,6 +239,7 @@ "and create a new shared link.": "i utwórz nowy link udostępniania.", "Android": "Android", "Anyone": "Każdy", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Bazowy adres URL API", "API Key": "Klucz API", @@ -302,6 +305,7 @@ "At time of event": "W momencie wydarzenia", "Attach File From Knowledge": "Dołącz plik z bazy wiedzy", "Attach Files": "Dołącz pliki", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Dołącz bazę wiedzy", "Attach Notes": "Dołącz notatki", "Attach Webpage": "Dołącz stronę www", @@ -444,8 +448,11 @@ "Chat Permissions": "Uprawnienia czatu", "Chat Tags Auto-Generation": "Automatyczne generowanie tagów czatu", "Chat unshared successfully.": "Udostępnianie czatu cofnięte.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "czaty", "Chats": "Czaty", + "Chats Open Sharing": "", "Chats Public Sharing": "Publiczne udostępnianie czatów", "Check Again": "Sprawdź ponownie", "Check for updates": "Sprawdź dostępność aktualizacji", @@ -453,6 +460,7 @@ "Choose a model before saving...": "Wybierz model przed zapisaniem...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -486,6 +494,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Wyczyść pamięć", "Clear Memory": "Wyczyść pamięć", @@ -579,6 +588,7 @@ "Confirm": "Potwierdź", "Confirm Password": "Potwierdź hasło", "Confirm Prompt from Embed": "Potwierdź prompt z osadzenia", + "Confirm recording": "", "Confirm your action": "Potwierdź działanie", "Confirm your new password": "Potwierdź nowe hasło", "Confirm Your Password": "Potwierdź swoje hasło", @@ -735,6 +745,7 @@ "Default to ALL": "Domyślnie WSZYSTKIE", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Domyślnie używa segmented retrieval dla lepszej precyzji. Zalecane w większości przypadków.", + "Default Upload Mode": "", "Default User Role": "Domyślna rola użytkownika", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -783,6 +794,7 @@ "Deselect": "Odznacz", "Detect Artifacts Automatically": "Wykrywaj artefakty automatycznie", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dyktuj", "Didn't fully follow instructions": "Nie w pełni wykonał instrukcje", "Direct": "Bezpośredni", @@ -854,6 +866,7 @@ "Download as SVG": "Pobierz jako SVG", "Download canceled": "Pobieranie anulowane", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -901,6 +914,7 @@ "Edit Terminal Connection": "Edytuj połączenie z terminalem", "Edit User": "Edytuj profil użytkownika", "Edit User Group": "Edytuj grupę użytkowników", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Edytuj treść workflow.json", "edited": "edytowano", @@ -934,6 +948,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Włącz, wyłącz lub dostosuj tagi reasoning (rozumowania). \"Włączone\" używa domyślnych, \"Wyłączone\" usuwa je, \"Własne\" pozwala zdefiniować tagi start/koniec.", "Enabled": "Włączone", + "End call": "", "End Tag": "Tag końcowy", "Endpoint": "", "Endpoint URL": "URL punktu końcowego", @@ -1195,6 +1210,7 @@ "Failed to remove member": "Nie udało się usunąć członka", "Failed to render diagram": "Nie udało się wyrenderować diagramu", "Failed to render visualization": "Nie udało się wyrenderować wizualizacji", + "Failed to save chat variables": "", "Failed to save connections": "Nie udało się zapisać połączeń", "Failed to save conversation": "Nie udało się zapisać rozmowy", "Failed to save models configuration": "Nie udało się zapisać konfiguracji modeli", @@ -1262,6 +1278,7 @@ "Folder updated successfully": "Folder zaktualizowany pomyślnie", "Folders": "Foldery", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Pytania nawiązujące", "Follow Up Generation": "Generowanie pytań nawiązujących", "Follow Up Generation Prompt": "Prompt generowania pytań nawiązujących", @@ -1309,6 +1326,7 @@ "Generate an image": "Wygeneruj obraz", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Generuj i edytuj obrazy", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Generuj parę wiadomości", "Generate suggested follow-up prompts after responses.": "", @@ -1487,6 +1505,7 @@ "Keep in Sidebar": "Zachowaj w pasku bocznym", "Key": "Klucz", "Key is required": "Klucz jest wymagany", + "key_name": "", "Keyboard": "", "Knowledge": "Baza wiedzy", "Knowledge Access": "Dostęp do bazy wiedzy", @@ -1560,9 +1579,9 @@ "List": "Lista", "List calendars, search, create, update, and delete calendar events": "Wyświetlaj kalendarze, wyszukuj, twórz, aktualizuj i usuwaj wydarzenia", "Listening...": "Słucham...", + "LiteLLM": "", "Live": "Na żywo", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Modele LLM mogą popełniać błędy. Weryfikuj ważne informacje.", "Loaded": "Załadowany", "Loader": "Loader", @@ -1601,6 +1620,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marzec", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown Header Text Splitter", "Max background": "", @@ -1673,7 +1694,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' został pomyślnie pobrany.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' jest już w kolejce pobierania.", - "Model {{modelId}} not found": "Nie znaleziono modelu {{modelId}}", "Model {{modelName}} deleted successfully": "Model {{modelName}} usunięty pomyślnie", "Model {{modelName}} is not vision capable": "Model {{modelName}} nie obsługuje widzenia (Vision)", "Model {{name}} is now {{status}}": "Model {{name}} jest teraz {{status}}", @@ -1772,8 +1792,11 @@ "New Webhook": "Nowy webhook", "new-channel": "nowy-kanal", "Next message": "Następna wiadomość", + "Next month": "", "Next page": "", "Next run": "Następne uruchomienie", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Brak przyznanych dostępów. Prywatne tylko dla Ciebie.", "No actions found": "", "No activity data": "Brak danych aktywności", @@ -1804,6 +1827,7 @@ "No files in this knowledge base.": "Brak plików w tej bazie wiedzy.", "No files yet. Upload files or run Python code to create them.": "Brak plików. Prześlij pliki lub uruchom kod Python, aby je utworzyć.", "No filters found": "", + "No folders": "", "No functions found": "Nie znaleziono funkcji", "No groups found": "Nie znaleziono grup", "No history available": "Brak dostępnej historii", @@ -1845,6 +1869,7 @@ "No tools accessible": "", "No tools found": "Nie znaleziono narzędzi", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Nie znaleziono użytkowników.", "No valves": "Brak valves", "No valves to update": "Brak valves do aktualizacji", @@ -1916,6 +1941,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ups! Pliki wciąż się przesyłają. Poczekaj na zakończenie.", "Oops! There was an error in the previous response.": "Ups! Wystąpił błąd w poprzedniej odpowiedzi.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ups! Używasz nieobsługiwanej metody (tylko frontend). Uruchom WebUI z backendu.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1993,6 +2019,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Treść nakładki dla oczekującego użytkownika", "Pending User Overlay Title": "Tytuł nakładki dla oczekującego użytkownika", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Odmowa dostępu do urządzeń multimedialnych", "Permission denied when accessing microphone": "Odmowa dostępu do mikrofonu", @@ -2056,6 +2083,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID służy do unikania konfliktów (dodawany do ID modelu). Zostaw puste aby wyłączyć", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Zapobiegaj tworzeniu plików", "Preview": "Podgląd", @@ -2063,7 +2091,10 @@ "Previous 30 days": "Ostatnie 30 dni", "Previous 7 days": "Ostatnie 7 dni", "Previous message": "Poprzednia wiadomość", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Prywatny", "Private conversation between selected users": "Prywatna rozmowa między wybranymi użytkownikami", "Production version updated": "Wersja produkcyjna zaktualizowana", @@ -2201,6 +2232,7 @@ "Reset Vector Storage/Knowledge": "Resetuj bazę wektorową/wiedzę", "Reset view": "Resetuj widok", "Response": "Odpowiedź", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Nie można włączyć powiadomień. Sprawdź uprawnienia przeglądarki.", "Response Splitting": "", "Response Watermark": "Znak wodny odpowiedzi", @@ -2209,6 +2241,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Wynik", "RESULT": "WYNIK", + "Retained Messages": "", "Retrieval": "Retrieval (Pobieranie)", "Retrieval Query Generation": "Generowanie zapytań Retrieval", "Retrieved {{count}} sources": "Pobrano {{count}} źródeł", @@ -2255,6 +2288,7 @@ "Scheduled time must be in the future": "Zaplanowany czas musi być w przyszłości", "Scopes": "", "Scroll On Branch Change": "Przewiń przy zmianie gałęzi", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Przewiń na górę", "Search": "Szukaj", @@ -2271,6 +2305,7 @@ "Search Files": "Szukaj plików", "Search filters": "", "Search Filters": "Filtry wyszukiwania", + "Search folders": "", "search for archived chats": "szukaj w zarchiwizowanych", "search for folders": "szukaj folderów", "search for pinned chats": "szukaj przypiętych", @@ -2356,6 +2391,7 @@ "Selected": "", "Selected model: {{modelName}}": "Wybrany model: {{modelName}}", "Selected model(s) do not support image inputs": "Wybrane modele nie obsługują obrazów", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantyczny", "Send": "Wyślij", "Send a Message": "Wyślij wiadomość", @@ -2476,6 +2512,7 @@ "Skills Public Sharing": "Publiczne udostępnianie umiejętności", "Skills Sharing": "Udostępnianie umiejętności", "Skip Cache": "Pomiń Cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Coś poszło nie tak :/", "Sonar": "Sonar", @@ -2513,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Kroki (Steps)", "Stop": "Przerwij", + "Stop camera": "", "Stop Download": "Zatrzymaj pobieranie", "Stop Generating": "Przerwij generowanie", "Stop Sequence": "Sekwencja stop", @@ -2544,6 +2582,7 @@ "Support": "Wsparcie", "Support this plugin:": "Wesprzyj ten plugin:", "Supported MIME Types": "Obsługiwane typy MIME", + "Switch camera": "", "Switch to JSON editor": "Przełącz na edytor JSON", "Switch to visual editor": "Przełącz na edytor wizualny", "Sync": "Synchronizuj", @@ -2742,6 +2781,7 @@ "Unmute": "Wyłącz wyciszenie", "Unpin": "Odepnij", "Unpin from Sidebar": "Odepnij od paska bocznego", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Cofnij udostępnianie czatu", @@ -2749,6 +2789,7 @@ "Untagged": "Bez tagów", "Untitled": "Bez tytułu", "Update": "Aktualizuj", + "Update All Models": "", "Update and Copy Link": "Aktualizuj i kopiuj link", "Update Email": "", "Update embedding model": "", @@ -2806,6 +2847,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "użytkownik", @@ -2820,6 +2862,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Oceny użytkowników (kciuki w górę/dół)", "User Status": "Status użytkownika", + "User Variables": "", "User Webhooks": "Webhooki użytkownika", "Username": "Nazwa użytkownika", "Username Claim": "", @@ -2834,10 +2877,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves zaktualizowane", "Valves updated successfully": "Valves zaktualizowane pomyślnie", "variable": "zmienna", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Sprawdź połączenie", "Verify SSL Certificate": "Weryfikuj certyfikat SSL", diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index 46622f80af..8556ea3ad0 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "Adicionar aos favoritos", "Add User": "Adicionar Usuário", "Add User Group": "Adicionar grupo de usuários", + "Add User Variable": "", "Add webhook": "Adicionar webhook", "Add webpage": "Adicionar página web", "Add your Open Terminal URL and API key in Settings → Integrations.": "Adicione a URL do Open Terminal e a chave de API em Configurações → Integrações.", @@ -197,6 +198,7 @@ "Allow User Location": "Permitir Localização do Usuário", "Allow users to access calendar features.": "Permita que os usuários acessem os recursos de calendário.", "Allow users to authenticate with an LDAP directory.": "Permita que os usuários se autentiquem com um diretório LDAP.", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "Permita que os usuários configurem webhooks em suas contas.", "Allow users to create accounts through OAuth.": "Permita que os usuários criem contas por meio do OAuth.", "Allow users to create and manage notes.": "Permita que os usuários criem e gerenciem notas.", @@ -230,6 +232,7 @@ "and create a new shared link.": "e criar um novo link compartilhado.", "Android": "Android", "Anyone": "Qualquer um", + "Anyone with the link can view": "", "API Auth String": "String de autenticação da API", "API Base URL": "URL Base da API", "API Key": "Chave API", @@ -295,6 +298,7 @@ "At time of event": "No horário do evento", "Attach File From Knowledge": "Anexar arquivo da base de conhecimento", "Attach Files": "Anexar arquivos", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Anexar Base de Conhecimento", "Attach Notes": "Anexar Notas", "Attach Webpage": "Anexar Página Web", @@ -437,8 +441,11 @@ "Chat Permissions": "Permissões de Chat", "Chat Tags Auto-Generation": "Tags de Chat Geradas Automaticamente", "Chat unshared successfully.": "Compartilhamento do chat removido com sucesso.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "chats", "Chats": "Chats", + "Chats Open Sharing": "", "Chats Public Sharing": "Compartilhamento Público de Chats", "Check Again": "Verificar Novamente", "Check for updates": "Verificar atualizações", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Escolha um modelo antes de salvar...", "Choose automatic, left-to-right, or right-to-left text flow.": "Escolha o fluxo de texto automático, da esquerda para a direita ou da direita para a esquerda.", "Choose fallback models for background tasks. Current Model follows the active chat model.": "Escolha modelos alternativos para tarefas em segundo plano. Modelo Atual acompanha o modelo ativo no chat.", + "Choose folder": "", "Choose how extracted text is split before indexing.": "Escolha como o texto extraído é dividido antes da indexação.", "Choose how uploaded documents are parsed before indexing.": "Escolha como os documentos enviados são analisados antes da indexação.", "Choose how web result pages are fetched and read.": "Escolha como as páginas de resultados da web são obtidas e lidas.", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "Claim usada como URL da imagem de perfil.", "Claim used as the stable user identifier.": "Claim usada como identificador estável do usuário.", "Claim used as the user email address.": "Claim usada como endereço de e-mail do usuário.", + "Clear": "", "Clear filters to reorder": "Limpe os filtros para reordenar", "Clear memory": "Limpar memória", "Clear Memory": "Limpar Memória", @@ -571,6 +580,7 @@ "Confirm": "Confirmar", "Confirm Password": "Confirmar Senha", "Confirm Prompt from Embed": "Confirmar Prompt do Embed", + "Confirm recording": "", "Confirm your action": "Confirme sua ação", "Confirm your new password": "Confirme sua nova senha", "Confirm Your Password": "Confirme sua senha", @@ -727,6 +737,7 @@ "Default to ALL": "Padrão para TODOS", "Default to memberOf": "Usar memberOf como padrão.", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Use a recuperação segmentada como padrão para extração de conteúdo focado e relevante; isso é recomendado para a maioria dos casos.", + "Default Upload Mode": "", "Default User Role": "Padrão para novos usuários", "Default webhook": "Webhook padrão", "Defines the behavior used for spoken conversations.": "Define o comportamento usado em conversas faladas.", @@ -775,6 +786,7 @@ "Deselect": "Desmarcar", "Detect Artifacts Automatically": "Detectar artefatos automaticamente", "Detect generated artifacts and show them in the artifact workspace.": "Detecte os artefatos gerados e exiba-os no workspace de artefatos.", + "Detected Variables": "", "Dictate": "Ditar", "Didn't fully follow instructions": "Não seguiu completamente as instruções", "Direct": "Direto", @@ -846,6 +858,7 @@ "Download as SVG": "Baixar como SVG", "Download canceled": "Download cancelado", "Download every user's chat history as JSON.": "Baixe o histórico de chat de todos os usuários como JSON.", + "Download failed": "", "Download the application database when supported.": "Baixe o banco de dados do aplicativo quando houver suporte.", "Download the current admin configuration as JSON.": "Baixe a configuração atual do administrador como JSON.", "Download your chat history as a JSON export.": "Baixe seu histórico de chat como uma exportação JSON.", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "Editar Conexão de Terminal", "Edit User": "Editar Usuário", "Edit User Group": "Editar Grupo de Usuários", + "Edit User Variable": "", "Edit webhook": "Editar webhook", "Edit workflow.json content": "Editar conteúdo do workflow.json", "edited": "editado", @@ -926,6 +940,7 @@ "Enable Web Search": "Habilitar Pesquisa na Web", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Habilite, desabilite ou personalize as tags de raciocínio usadas pelo modelo. \"Ativado\" usa tags padrão, \"Desativado\" desativa as tags de raciocínio e \"Personalizado\" permite que você especifique suas próprias tags de início e fim.", "Enabled": "Ativado", + "End call": "", "End Tag": "Tag final", "Endpoint": "Endpoint", "Endpoint URL": "URL do Endpoint", @@ -1185,6 +1200,7 @@ "Failed to remove member": "Falha ao remover membro", "Failed to render diagram": "Falha ao renderizar o diagrama", "Failed to render visualization": "Falha ao renderizar a visualização", + "Failed to save chat variables": "", "Failed to save connections": "Falha ao salvar conexões", "Failed to save conversation": "Falha ao salvar a conversa", "Failed to save models configuration": "Falha ao salvar a configuração dos modelos", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "Pasta atualizada com sucesso", "Folders": "Pastas", "Folders Sharing": "Compartilhamento de Pastas", + "Follow assistant responses as they are generated.": "", "Follow up": "Acompanhamento", "Follow Up Generation": "Geração de Acompanhamento", "Follow Up Generation Prompt": "Prompt para Geração dos Acompanhamentos", @@ -1299,6 +1316,7 @@ "Generate an image": "Gerar uma imagem", "Generate an image prompt before sending the request.": "Gere um prompt de imagem antes de enviar a solicitação.", "Generate and edit images": "Gere e edite imagens", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "Gere títulos de chat automaticamente a partir do conteúdo da conversa.", "Generate Message Pair": "Gerar par de mensagens", "Generate suggested follow-up prompts after responses.": "Gere sugestões de prompts de acompanhamento após as respostas.", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Manter na barra lateral", "Key": "Chave", "Key is required": "Chave é obrigatória", + "key_name": "", "Keyboard": "Teclado", "Knowledge": "Conhecimento", "Knowledge Access": "Acesso ao Conhecimento", @@ -1550,9 +1569,9 @@ "List": "Lista", "List calendars, search, create, update, and delete calendar events": "Listar calendários, pesquisar, criar, atualizar e excluir eventos do calendário", "Listening...": "Escutando...", + "LiteLLM": "", "Live": "Ao vivo", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.", "Loaded": "Carregado", "Loader": "Carregador", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "Mapeie as entradas dos nós do fluxo de trabalho usadas na geração de imagens.", "Mapped Source": "Fonte Mapeada", "March": "Março", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Separador de texto de cabeçalho Markdown", "Max background": "Máximo em segundo plano", @@ -1663,7 +1684,6 @@ "Model": "Modelo", "Model '{{modelName}}' has been successfully downloaded.": "Modelo '{{modelName}}' foi baixado com sucesso.", "Model '{{modelTag}}' is already in queue for downloading.": "Modelo '{{modelTag}}' já está na fila para download.", - "Model {{modelId}} not found": "Modelo {{modelId}} não encontrado", "Model {{modelName}} deleted successfully": "Modelo {{modelName}} excluído com sucesso", "Model {{modelName}} is not vision capable": "Modelo {{modelName}} não é capaz de visão", "Model {{name}} is now {{status}}": "Modelo {{name}} está agora {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "Novo Webhook", "new-channel": "novo-canal", "Next message": "Próxima mensagem", + "Next month": "", "Next page": "Próxima página", "Next run": "Próxima execução", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Sem permissões de acesso. Privacidade exclusiva para você.", "No actions found": "Nenhuma ação encontrada", "No activity data": "Sem dados de atividade", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "Não existem arquivos nesta base de conhecimento.", "No files yet. Upload files or run Python code to create them.": "Nenhum arquivo ainda. Envie arquivos ou execute código Python para criá-los.", "No filters found": "Nenhum filtro encontrado", + "No folders": "", "No functions found": "Nenhuma função encontrada", "No groups found": "Nenhum grupo encontrado", "No history available": "Não há histórico disponível.", @@ -1835,6 +1859,7 @@ "No tools accessible": "Nenhuma ferramenta acessível", "No tools found": "Nenhuma ferramenta encontrada", "No usage data found": "Nenhum dado de uso encontrado", + "No user variables configured.": "", "No users were found.": "Nenhum usuário foi encontrado.", "No valves": "Sem configurações", "No valves to update": "Nenhuma configuração para atualizar", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ops! Ainda há arquivos sendo enviados. Por favor, aguarde a conclusão do envio.", "Oops! There was an error in the previous response.": "Ops! Houve um erro na resposta anterior.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ops! Você está usando um método não suportado (somente frontend). Por favor, sirva a WebUI a partir do backend.", + "Open": "", "Open automation": "Abrir automação", "Open create menu": "Abrir menu Criar", "Open detail blocks by default.": "Abra os blocos de detalhes por padrão.", @@ -1983,6 +2009,7 @@ "Pending Accounts": "Contas Pendentes", "Pending User Overlay Content": "Conteúdo de sobreposição de usuário pendente", "Pending User Overlay Title": "Título de sobreposição de usuário pendente", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "Exclua permanentemente todos os chats após a confirmação.", "Permission denied when accessing media devices": "Permissão negada ao acessar dispositivos de mídia", "Permission denied when accessing microphone": "Permissão negada ao acessar o microfone", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "Códigos dos idiomas preferidos para transcrição, separados por vírgulas.", "Prefix ID": "Prefixo ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "O ID de prefixo é utilizado para evitar conflitos com outras conexões, adicionando um prefixo aos IDs dos modelos - deixe em branco para desativar.", + "Preparing download...": "", "Press keys...": "Pressione as teclas...", "Prevent File Creation": "Impedir a criação de arquivos", "Preview": "Visualização", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Últimos 30 dias", "Previous 7 days": "Últimos 7 dias", "Previous message": "Mensagem anterior", + "Previous month": "", "Previous page": "Página anterior", + "Previous slide": "", + "Previous version": "", "Private": "Privado", "Private conversation between selected users": "Conversa privada entre usuários selecionados", "Production version updated": "Versão de produção atualizada", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Redefinir Armazenamento de Vetores/Conhecimento", "Reset view": "Redefinir visualização", "Response": "Resposta", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Notificações de resposta não podem ser ativadas pois as permissões do site foram negadas. Por favor, visite as configurações do seu navegador para conceder o acesso necessário.", "Response Splitting": "Divisão de respostas", "Response Watermark": "Marca d'água de resposta", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "Restrinja ou exclua domínios usando uma lista separada por vírgulas.", "Result": "Resultado", "RESULT": "Resultado", + "Retained Messages": "", "Retrieval": "Recuperação", "Retrieval Query Generation": "Geração de Consulta de Recuperação", "Retrieved {{count}} sources": "{{count}} fontes recuperadas", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "O horário agendado deve ser no futuro.", "Scopes": "Escopos", "Scroll On Branch Change": "Rolar na mudança de ramo", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "Role até a ramificação ativa ao alternar entre ramificações de resposta.", "Scroll to Top": "Rolar para o topo", "Search": "Pesquisar", @@ -2258,6 +2292,7 @@ "Search Files": "Pesquisar arquivos", "Search filters": "Filtros de pesquisa", "Search Filters": "Pesquisar Filtros", + "Search folders": "", "search for archived chats": "pesquisar por chats arquivados", "search for folders": "procurar pastas", "search for pinned chats": "pesquisar por chats fixados", @@ -2343,6 +2378,7 @@ "Selected": "Selecionado", "Selected model: {{modelName}}": "Modelo selecionado: {{modelName}}", "Selected model(s) do not support image inputs": "Modelo(s) selecionado(s) não suportam entradas de imagem", + "Selected models define incompatible Chat Variables.": "", "semantic": "semântica", "Send": "Enviar", "Send a Message": "Enviar uma Mensagem", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "Compartilhamento público de skills", "Skills Sharing": "Compartilhamento de skills", "Skip Cache": "Pular cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "Ignore os resultados do Marker em cache e execute a inferência novamente.", "Something went wrong :/": "Algo deu errado :/", "Sonar": "Sonar", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Passos", "Stop": "Parar", + "Stop camera": "", "Stop Download": "Parar download", "Stop Generating": "Parar de Gerar", "Stop Sequence": "Sequência de Parada", @@ -2530,6 +2568,7 @@ "Support": "Suporte", "Support this plugin:": "Apoie este plugin:", "Supported MIME Types": "Tipos MIME suportados", + "Switch camera": "", "Switch to JSON editor": "Mudar para editor JSON", "Switch to visual editor": "Mudar para editor visual", "Sync": "Sincronizar", @@ -2728,6 +2767,7 @@ "Unmute": "Reativar som", "Unpin": "Desfixar", "Unpin from Sidebar": "Desfixar da barra lateral", + "Unread": "", "Unshare All": "Descompartilhar Tudo", "Unshare All Shared Chats": "Descompartilhar Todos os Chats Compartilhados", "Unshare Chat": "Cancelar compartilhamento do chat", @@ -2735,6 +2775,7 @@ "Untagged": "Sem tag", "Untitled": "Sem título", "Update": "Atualizar", + "Update All Models": "", "Update and Copy Link": "Atualizar e Copiar Link", "Update Email": "Atualizar Email", "Update embedding model": "Atualizar modelo de embedding", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "Use formatação estilizada ao exportar chats para PDF.", "Use the active chat title as the browser tab title.": "Use o título do chat ativo como título da aba do navegador.", "Use the rich composer instead of a plain textarea.": "Use o editor de texto rico em vez de uma área de texto simples.", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "Use TLS ao se conectar ao servidor LDAP.", "Use Web Search?": "Usar Pesquisa na Web?", "user": "usuário", @@ -2806,6 +2848,7 @@ "User Preview": "Visualização do Usuário", "User ratings (thumbs up/down)": "Avaliações dos usuários (polegar para cima/polegar para baixo)", "User Status": "Status do usuário", + "User Variables": "", "User Webhooks": "Webhooks do usuário", "Username": "Nome do Usuário", "Username Claim": "Reivindicação de Nome de Usuário", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "Unidades de tempo válidas: 's', 'm', 'h', 'd', 'w' ou '-1' para não expirar.", "Validate Certificate": "Validar certificado", "Validate SSL certificates when fetching web content.": "Valide os certificados SSL ao obter conteúdo da web.", + "Value": "", "Valves": "Configurações", "Valves updated": "Configurações atualizadas", "Valves updated successfully": "Configurações atualizadas com sucesso", "variable": "variável", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "Campo de Vetor", "Verify Connection": "Verificar conexão", "Verify SSL Certificate": "Verificar certificado SSL", diff --git a/src/lib/i18n/locales/pt-PT/translation.json b/src/lib/i18n/locales/pt-PT/translation.json index df6a0cd2ea..695b126f85 100644 --- a/src/lib/i18n/locales/pt-PT/translation.json +++ b/src/lib/i18n/locales/pt-PT/translation.json @@ -64,7 +64,7 @@ "A collaboration channel where people join as members": "Um canal de colaboração onde as pessoas entram como membros", "A discussion channel where access is controlled by groups and permissions": "Um canal de discussão onde o acesso é controlado por grupos e permissões", "A new version (v{{LATEST_VERSION}}) is now available.": "Uma nova versão (v{{LATEST_VERSION}}) está agora disponível.", - "A private conversation between you and selected users": "Uma conversa privada entre você e utilizadores selecionados", + "A private conversation between you and selected users": "Uma conversa privada entre si e os utilizadores selecionados", "a user": "um utilizador", "About": "Acerca de", "Accept Autocomplete Generation\nJump to Prompt Variable": "Aceitar Geração do Preenchimento Automático\nIr para Variável de Prompt", @@ -82,7 +82,7 @@ "Action": "Ação", "Action Required for Chat Log Storage": "É necessária uma ação para guardar o registo da conversa", "Actions": "Ações", - "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Ative este comando digitando \"/{{COMMAND}}\" na entrada da conversa.", + "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Ative este comando ao digitar \"/{{COMMAND}}\" na entrada da conversa.", "Active": "Ativo", "Active Users": "Utilizadores Ativos", "Activity": "Atividade", @@ -96,7 +96,7 @@ "Add Access": "Adicionar Acesso", "Add Arena Model": "Adicionar Modelo Arena", "Add banner": "", - "Add Connection": "Adicionar Conexão", + "Add Connection": "Adicionar Ligação", "Add Content": "Adicionar Conteúdo", "Add content here": "Adicionar conteúdo aqui", "Add Custom Parameter": "Adicionar Parâmetro Personalizado", @@ -124,9 +124,10 @@ "Add to favorites": "Adicionar aos favoritos", "Add User": "Adicionar Utilizador", "Add User Group": "Adicionar Grupo de Utilizadores", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Adicionar página web", - "Add your Open Terminal URL and API key in Settings → Integrations.": "Adicione o URL do Open Terminal e a chave API em Configurações → Integrações.", + "Add your Open Terminal URL and API key in Settings → Integrations.": "Adicione o URL do Open Terminal e a chave API em Definições → Integrações.", "Additional Config": "Configuração Adicional", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "Opções de configuração adicionais para o marcador. Isto deve ser uma string JSON com pares chave-valor. Por exemplo, '{\"key\": \"value\"}'. As chaves suportadas incluem: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level", "Additional Docling parameters in JSON format.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Permitir Localização do Utilizador", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "e criar um novo link partilhado.", "Android": "Android", "Anyone": "Qualquer pessoa", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Base da API", "API Key": "Chave da API", @@ -255,12 +258,12 @@ "API Version is required": "A versão da API é obrigatória", "Append a watermark to assistant responses when configured.": "", "Application DN": "DN da Aplicação", - "Application DN Password": "Senha do DN da Aplicação", + "Application DN Password": "Palavra-passe do DN da Aplicação", "applies to all users with the \"user\" role": "aplica-se a todos os utilizadores com o papel \"utilizador\"", "Apply image compression to channel uploads too.": "", "Apply voice-specific instructions while voice mode is active.": "", "April": "Abril", - "Archive": "Arquivo", + "Archive": "Arquivar", "Archive All": "Arquivar Tudo", "Archive All Chats": "Arquivar todas as conversas", "Archived Chats": "Conversas arquivadas", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "Anexar Ficheiro do Conhecimento", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Anexar Conhecimento", "Attach Notes": "Anexar Notas", "Attach Webpage": "Anexar Página Web", @@ -355,7 +359,7 @@ "Base DN used when searching for users.": "", "Base Model (From)": "Modelo Base (De)", "Base Model is required.": "", - "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "O cache da lista de modelos base acelera o acesso ao buscar apenas os modelos base na inicialização ou ao salvar as configurações—mais rápido, mas pode não mostrar alterações recentes nos modelos base.", + "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "O cache da lista de modelos base acelera o acesso ao buscar apenas os modelos base na inicialização ou ao guardar as definições—mais rápido, mas pode não mostrar alterações recentes nos modelos base.", "Base URL": "", "Bearer": "Bearer", "before": "antes", @@ -407,7 +411,7 @@ "Certificate file used for TLS verification.": "", "Certificate Path": "Caminho do Certificado", "Change folder icon": "Alterar ícone da pasta", - "Change Password": "Alterar Senha", + "Change Password": "Alterar Palavra-passe", "Change User Role": "Alterar Função do Utilizador", "Channel": "Canal", "Channel deleted successfully": "Canal eliminado com sucesso", @@ -437,8 +441,11 @@ "Chat Permissions": "Permissões da Conversa", "Chat Tags Auto-Generation": "Geração Automática de Etiquetas da Conversa", "Chat unshared successfully.": "Conversa não partilhada com sucesso.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "conversas", "Chats": "Conversas", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Verifique novamente", "Check for updates": "Verificar atualizações", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Escolha um modelo antes de guardar...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Limpar memória", "Clear Memory": "Limpar Memória", @@ -489,7 +498,7 @@ "Click here for filter guides.": "Clique aqui para guias de filtro.", "Click here for help.": "Clique aqui para obter ajuda.", "Click here to": "Clique aqui para", - "Click here to download user import template file.": "Clique aqui para transferir o arquivo de modelo de importação de utilizador.", + "Click here to download user import template file.": "Clique aqui para transferir o ficheiro de modelo de importação de utilizador.", "Click here to learn more about faster-whisper and see the available models.": "Clique aqui para saber mais sobre o faster-whisper e ver os modelos disponíveis.", "Click here to see available models.": "Clique aqui para ver os modelos disponíveis.", "Click here to select": "Clique aqui para selecionar", @@ -502,7 +511,7 @@ "Click to rebind": "", "Client ID": "", "Client Secret": "", - "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permissão de escrita na área de transferência negada. Por favor, verifique as configurações do seu navegador para conceder o acesso necessário.", + "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permissão de escrita na área de transferência negada. Por favor, verifique as definições do seu navegador para conceder o acesso necessário.", "Clone": "Clonar", "Clone Chat": "Clonar Conversa", "Clone of {{TITLE}}": "Clone de {{TITLE}}", @@ -510,7 +519,7 @@ "Close Banner": "Fechar Banner", "Close chat controls": "Fechar controlos de conversa", "Close citation modal": "Fechar janela de citação", - "Close Configure Connection Modal": "Fechar Configurar Janela de Conexão Modal", + "Close Configure Connection Modal": "Fechar a janela de configuração da ligação", "Close feedback": "Fechar feedback", "Close modal": "Fechar janela", "Close Modal": "Fechar Janela", @@ -569,10 +578,11 @@ "Config imported successfully": "Configuração importada com sucesso", "Configure": "Configurar", "Confirm": "Confirmar", - "Confirm Password": "Confirmar Senha", + "Confirm Password": "Confirmar Palavra-passe", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Confirme sua ação", - "Confirm your new password": "Confirme sua a nova palavra-passe", + "Confirm your new password": "Confirme a sua nova palavra-passe", "Confirm Your Password": "Confirme a sua palavra-passe", "Connect code execution to a Jupyter server endpoint.": "", "Connect code interpreter to a Jupyter server endpoint.": "", @@ -682,7 +692,7 @@ "Ctrl+Enter to Send": "Ctrl+Enter para Enviar", "Current": "", "Current Model": "Modelo Atual", - "Current Password": "Senha Atual", + "Current Password": "Palavra-passe Atual", "Current streak": "", "Custom": "Personalizado", "Custom color": "", @@ -727,6 +737,7 @@ "Default to ALL": "Predefinir para TODOS", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Predefinir para recuperação segmentada para extração de conteúdo focada e relevante, isso é recomendado para a maioria dos casos.", + "Default Upload Mode": "", "Default User Role": "Função de Utilizador Padrão", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Detatar Artefactos Automaticamente", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Ditar", "Didn't fully follow instructions": "Não seguiu instruções com precisão", "Direct": "Direto", @@ -846,6 +858,7 @@ "Download as SVG": "Transferir como SVG", "Download canceled": "Transfência cancelada", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "Editar Ligação ao Terminal", "Edit User": "Editar Utilizador", "Edit User Group": "Editar Grupo de Utilizadores", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Editar o conteúdo workflow.json", "edited": "editado", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Ativar, desativar, ou customizar as etiquetas de raciocínio utilizadas pelo modelo. \"Ativado\" utiliza as etiquetas predefinidas, \"Desativado\" desliga as etiquetas de raciocínio, e \"Personalizado\" permite a espeficicação das etiquetas de começo e fim. ", "Enabled": "Ativado", + "End call": "", "End Tag": "Etiqueta de Fim", "Endpoint": "", "Endpoint URL": "URL do Endpoint", @@ -986,7 +1001,7 @@ "Enter Jina API Base URL": "Introduzir URL Base da API do Jina", "Enter Jina API Key": "Introduzir Chave da API do Jina", "Enter JSON config (e.g., {\"disable_links\": true})": "Introduzir configuração JSON (por exemplo, {\"disable_links\": true})", - "Enter Jupyter Password": "Introduzir Senha do Jupyter", + "Enter Jupyter Password": "Introduzir Palavra-passe do Jupyter", "Enter Jupyter Token": "Introduzir Token do Jupyter", "Enter Jupyter URL": "Introduzir URL do Jupyter", "Enter Kagi Search API Key": "Introduzir a Chave da API do Kagi Search", @@ -1078,7 +1093,7 @@ "ERROR": "ERRO", "Error accessing directory": "Erro ao aceder ao diretório", "Error accessing Google Drive: {{error}}": "Erro ao aceder ao Google Drive: {{error}}", - "Error accessing media devices.": "Erro ao aceder aos dispositivos de mídia", + "Error accessing media devices.": "Erro ao aceder aos dispositivos de multimédia", "Error deleting model: {{error}}": "", "Error starting recording.": "Erro ao começar a gravação.", "Error unloading model: {{error}}": "Erro ao descarregar o modelo: {{error}}", @@ -1185,6 +1200,7 @@ "Failed to remove member": "Falha ao remover membro", "Failed to render diagram": "Falha ao renderizar diagrama", "Failed to render visualization": "Falha ao renderizar visualização", + "Failed to save chat variables": "", "Failed to save connections": "Falha ao guardar ligações", "Failed to save conversation": "Falha ao guardar a conversa", "Failed to save models configuration": "Falha ao guardar configuração de modelos", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "Pasta atualizada com sucesso", "Folders": "Pastas", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Acompanhamento", "Follow Up Generation": "Geração de Acompanhamento", "Follow Up Generation Prompt": "Prompt de Geração de Acompanhamento", @@ -1299,6 +1316,7 @@ "Generate an image": "Gerar uma imagem", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Gerar e editar imagens", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Gerar Par de Mensagens", "Generate suggested follow-up prompts after responses.": "", @@ -1367,7 +1385,7 @@ "Hourly": "", "Hourly Messages": "Mensagens Horárias", "How can I help you today?": "Como posso ajudá-lo hoje?", - "How would you rate this response?": "Como você avaliaria esta resposta?", + "How would you rate this response?": "Como avaliaria esta resposta?", "HTML": "HTML", "http://localhost:8000": "http://localhost:8000", "https://mineru.net/api/v4": "https://mineru.net/api/v4", @@ -1422,7 +1440,7 @@ "Info": "Informação", "Initials": "Iniciais", "Inject entire documents as context for comprehensive processing.": "", - "Inject file content into conversation context": "Injetar o conteúdo do arquivo no contexto da conversa", + "Inject file content into conversation context": "Injetar o conteúdo do ficheiro no contexto da conversa", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Injetar todo o conteúdo como contexto para um processamento abrangente, isso é recomendado para consultas complexas.", "Inject the entire content as context for comprehensive processing.": "", "Input": "Entrada", @@ -1441,9 +1459,9 @@ "Integration": "Integração", "Integrations": "Integrações", "Interface": "Interface", - "Interface Settings Access": "Acesso às Configurações da Interface", - "Invalid file format.": "Formato de arquivo inválido.", - "Invalid JSON file": "Arquivo JSON inválido", + "Interface Settings Access": "Acesso às Definições da Interface", + "Invalid file format.": "Formato de ficheiro inválido.", + "Invalid JSON file": "Ficheiro JSON inválido", "Invalid JSON format": "", "Invalid JSON format for ComfyUI Edit Workflow.": "Formato JSON inválido para ComfyUI Edit Workflow.", "Invalid JSON format for ComfyUI Workflow.": "Formato JSON inválido para ComfyUI Workflow.", @@ -1451,7 +1469,7 @@ "Invalid JSON format in {{NAME}}": "Formato JSON inválido em {{NAME}}", "Invalid JSON format in Additional Config": "Formato JSON inválido em Configuração Adicional", "Invalid JSON format in MinerU Parameters": "Formato JSON inválido em Parâmetros MinerU", - "is typing...": "está digitando...", + "is typing...": "está a digitar...", "Italic": "Itálico", "January": "Janeiro", "Jina API Base URL": "URL Base da API do Jina", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "Manter na Barra Lateral", "Key": "Chave", "Key is required": "Chave é obrigatória", + "key_name": "", "Keyboard": "", "Knowledge": "Conhecimento", "Knowledge Access": "Acesso ao Conhecimento", @@ -1550,9 +1569,9 @@ "List": "Lista", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "A ouvir...", + "LiteLLM": "", "Live": "Ao vivo", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.", "Loaded": "", "Loader": "Carregador", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Março", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Divisor de Texto de Cabeçalho Markdown", "Max background": "", @@ -1617,7 +1638,7 @@ "May": "Maio", "MBR": "MBR", "MCP": "MCP", - "MCP support is experimental and its specification changes often, which can lead to incompatibilities. OpenAPI specification support is directly maintained by the Open WebUI team, making it the more reliable option for compatibility.": "O suporte MCP é experimental e sua especificação muda frequentemente, o que pode levar a incompatibilidades. O suporte à especificação OpenAPI é mantido diretamente pela equipe Open WebUI, tornando-o a opção mais confiável para compatibilidade.", + "MCP support is experimental and its specification changes often, which can lead to incompatibilities. OpenAPI specification support is directly maintained by the Open WebUI team, making it the more reliable option for compatibility.": "O suporte MCP é experimental e a sua especificação muda frequentemente, o que pode levar a incompatibilidades. O suporte à especificação OpenAPI é mantido diretamente pela equipa Open WebUI, tornando-o a opção mais confiável para compatibilidade.", "Medium": "Médio", "Member removed successfully": "Membro removido com sucesso", "members": "membros", @@ -1644,7 +1665,7 @@ "Message text...": "", "messages": "mensagens", "Messages": "Mensagens", - "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Mensagens que você enviar após criar o seu link não serão partilhadas. Os utilizadores com o URL poderão visualizar a conversa partilhada.", + "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "As mensagens que enviar após criar o seu link não serão partilhadas. Os utilizadores com o URL poderão visualizar a conversa partilhada.", "Metadata Field": "", "Microsoft OneDrive": "Microsoft OneDrive", "Microsoft OneDrive (personal)": "Microsoft OneDrive (pessoal)", @@ -1663,7 +1684,6 @@ "Model": "Modelo", "Model '{{modelName}}' has been successfully downloaded.": "O modelo '{{modelName}}' foi descarregado com sucesso.", "Model '{{modelTag}}' is already in queue for downloading.": "O modelo '{{modelTag}}' já está na fila para descarregar.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "O modelo {{modelName}} não é capaz de visão", "Model {{name}} is now {{status}}": "Modelo {{name}} agora é {{status}}", @@ -1754,7 +1774,7 @@ "New Function": "Nova Função", "New Group": "Novo Grupo", "New Note": "Nova Nota", - "New Password": "Nova Senha", + "New Password": "Nova Palavra-passe", "New Sign Ups": "", "New Temporary Chat": "Nova Conversa Temporária", "New Terminal": "Novo Terminal", @@ -1762,9 +1782,12 @@ "New Webhook": "Novo Webhook", "new-channel": "novo-canal", "Next message": "Próxima mensagem", + "Next month": "", "Next page": "", "Next run": "", - "No access grants. Private to you.": "Sem concessões de acesso. Privado para você.", + "Next slide": "", + "Next version": "", + "No access grants. Private to you.": "Sem concessões de acesso. Privado para si.", "No actions found": "", "No activity data": "Sem dados de atividade", "No additional headers are sent unless configured.": "", @@ -1780,7 +1803,7 @@ "No content": "Sem conteúdo", "No content found": "Nenhum conteúdo encontrado", "No content to speak": "Nenhum conteúdo para falar", - "No conversation to save": "Nenhuma conversa para salvar", + "No conversation to save": "Nenhuma conversa para guardar", "No data": "Sem dados", "No data found": "Nenhum dado encontrado", "No description": "", @@ -1794,11 +1817,12 @@ "No files in this knowledge base.": "Nenhum ficheiro nesta base de conhecimento.", "No files yet. Upload files or run Python code to create them.": "Ainda não há ficheiros. Faça upload de ficheiros ou execute código Python para criá-los.", "No filters found": "", + "No folders": "", "No functions found": "Nenhuma função encontrada", "No groups found": "Nenhum grupo encontrado", "No history available": "Nenhum histórico disponível", "No HTML, CSS, or JavaScript content found.": "Nenhum conteúdo HTML, CSS ou JavaScript encontrado.", - "No inference engine with management support found": "Nenhum motor de inferência com suporte de gerenciamento encontrado", + "No inference engine with management support found": "Nenhum motor de inferência com suporte de gestão encontrado", "No kernel": "Nenhum kernel", "No knowledge bases accessible": "", "No knowledge bases found.": "Nenhuma base de conhecimento encontrada.", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "Nenhuma ferramenta encontrada", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Nenhum utilizador encontrado", "No valves": "Nenhuma válvula", "No valves to update": "Nenhuma válvula para atualizar", @@ -1847,11 +1872,11 @@ "Not Registered": "Não registrado", "Not scheduled": "", "Note": "Nota", - "Note deleted successfully": "Nota excluída com sucesso", + "Note deleted successfully": "Nota eliminada com sucesso", "Note Menu": "", "Notes": "Notas", "Notes Public Sharing": "Patilha Pública de Notas", - "Notes Sharing": "Compartilhamento de Notas", + "Notes Sharing": "Partilha de Notas", "Nothing to compact": "", "Notification Sound": "Som de Notificação", "Notification Targets": "", @@ -1879,7 +1904,7 @@ "OLED Dark": "OLED Escuro", "Ollama": "Ollama", "Ollama API": "Ollama API", - "Ollama API settings updated": "Configurações da API Ollama atualizadas", + "Ollama API settings updated": "Definições da API Ollama atualizadas", "Ollama Cloud API Key": "Chave da API Ollama Cloud", "Ollama endpoint used for embeddings.": "", "Ollama Version": "Versão do Ollama", @@ -1888,8 +1913,8 @@ "Once": "", "OneDrive": "OneDrive", "Only active during Voice Mode.": "", - "Only active when \"Paste Large Text as File\" setting is toggled on.": "Apenas ativo quando a configuração \"Colar Texto Grande como Arquivo\" está ativada.", - "Only active when the chat input is in focus and an LLM is generating a response.": "Apenas ativo quando a entrada do chat está em foco e um LLM está gerando uma resposta.", + "Only active when \"Paste Large Text as File\" setting is toggled on.": "Apenas ativo quando a definição \"Colar Texto Grande como Ficheiro\" está ativada.", + "Only active when the chat input is in focus and an LLM is generating a response.": "Apenas ativo quando a entrada da conversa está em foco e um LLM está a gerar uma resposta.", "Only active when the chat input is in focus.": "Apenas ativo quando a entrada do chat está em foco.", "Only alphanumeric characters and hyphens are allowed": "Apenas caracteres alfanuméricos e hífens são permitidos", "Only alphanumeric characters and hyphens are allowed in the command string.": "Apenas caracteres alfanuméricos e hífens são permitidos na string de comando.", @@ -1897,19 +1922,20 @@ "Only collections can be edited, create a new knowledge base to edit/add documents.": "Apenas coleções podem ser editadas, crie uma nova base de conhecimento para editar/adicionar documentos.", "Only install functions from sources you trust.": "", "Only install tools from sources you trust.": "", - "Only invited users can access": "Apenas utilizadores convidados podem acessar", + "Only invited users can access": "Apenas utilizadores convidados podem aceder", "Only return documents with a score greater than or equal to this value.": "", - "Only select users and groups with permission can access": "Apenas utilizadores e grupos selecionados com permissão podem acessar", + "Only select users and groups with permission can access": "Apenas utilizadores e grupos selecionados com permissão podem aceder", "Only sync new/updated chats": "Apenas sincronizar chats novos/atualizados", "Only when away": "", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Epá! Parece que o URL é inválido. Verifique novamente e tente outra vez.", - "Oops! There are files still uploading. Please wait for the upload to complete.": "Epá! Ainda há arquivos sendo enviados. Por favor, aguarde a conclusão do envio.", + "Oops! There are files still uploading. Please wait for the upload to complete.": "Epá! Ainda há ficheiros a ser enviados. Por favor, aguarde a conclusão do envio.", "Oops! There was an error in the previous response.": "Epá! Ocorreu um erro na resposta anterior.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Epá! Está a utilizar um método não suportado (somente frontend). Por favor, sirva o WebUI a partir do backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", - "Open file": "Abrir arquivo", + "Open file": "Abrir ficheiro", "Open in full screen": "Abrir em ecrã inteiro", "Open in new tab": "", "Open link": "Abrir link", @@ -1918,7 +1944,7 @@ "Open Modal To Manage Image Compression": "Abrir Janela para Gerir Compressão de Imagem", "Open Model Selector": "Abrir Selector de Modelos", "Open note": "", - "Open Settings": "Abrir Configurações", + "Open Settings": "Abrir Definições", "Open Sidebar": "Abrir Barra Lateral", "Open Terminal": "Abrir Terminal", "Open the changelog modal after sign-in when enabled.": "", @@ -1933,7 +1959,7 @@ "OpenAI": "OpenAI", "OpenAI API": "API OpenAI", "OpenAI API Key is required.": "A Chave da API OpenAI é obrigatória.", - "OpenAI API settings updated": "Configurações da API OpenAI atualizadas", + "OpenAI API settings updated": "Definições da API OpenAI atualizadas", "OpenAI URL/Key required.": "URL/Chave da API OpenAI é necessária.", "OpenAI-compatible embeddings endpoint.": "", "OpenAPI": "OpenAPI", @@ -1963,13 +1989,13 @@ "Paginate": "Paginar", "Parameters": "Parâmetros", "Parent message not found": "Mensagem pai não encontrada", - "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Participe nos rankings e avaliações da comunidade! Sincronizar estatísticas de uso agregadas ajuda a impulsionar a pesquisa e melhorias no Open WebUI. Sua privacidade é primordial: nenhum conteúdo de mensagem é compartilhado.", + "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Participe nos rankings e avaliações da comunidade! Sincronizar estatísticas de uso agregadas ajuda a impulsionar a pesquisa e melhorias no Open WebUI. A sua privacidade é primordial: nenhum conteúdo de mensagem é partilhado.", "Passthrough params": "", - "Password": "Senha", + "Password": "Palavra-passe", "Password for the bind DN.": "", "Passwords do not match.": "As palavras-passe não coincidem.", "Paste inserted prompts as rich text when possible.": "", - "Paste Large Text as File": "Colar Texto Grande como Arquivo", + "Paste Large Text as File": "Colar Texto Grande como Ficheiro", "Path": "", "Path copied": "", "Paused": "", @@ -1981,8 +2007,9 @@ "pending": "pendente", "Pending": "Pendente", "Pending Accounts": "", - "Pending User Overlay Content": "Conteúdo de Sobreposição de Usuário Pendente", - "Pending User Overlay Title": "Título de Sobreposição de Usuário Pendente", + "Pending User Overlay Content": "Conteúdo de Sobreposição de Utilizador Pendente", + "Pending User Overlay Title": "Título de Sobreposição de Utilizador Pendente", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "A permissão foi negada ao aceder aos dispositivos de media", "Permission denied when accessing microphone": "A permissão foi negada ao aceder ao microfone", @@ -2018,7 +2045,7 @@ "Playwright WebSocket URL": "URL do WebSocket do Playwright", "Please carefully review the following warnings:": "Por favor, reveja cuidadosamente os seguintes avisos:", "Please connect all required integrations before sending a message": "", - "Please do not close the settings page while loading the model.": "Por favor, não feche a página de configurações enquanto o modelo está a ser carregado.", + "Please do not close the settings page while loading the model.": "Por favor, não feche a página de definições enquanto o modelo está a ser carregado.", "Please enter a message or attach a file.": "Por favor, insira uma mensagem ou anexe um ficheiro.", "Please enter a prompt": "Por favor, insira um prompt", "Please enter a valid ID": "Por favor, insira um ID válido", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID de Prefixo", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "O ID de Prefixo é usado para evitar conflitos com outras ligações, adicionando um prefixo aos IDs dos modelos - deixe vazio para desativar", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Prevenir Criação de Ficheiros", "Preview": "Pré-visualização", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Últimos 30 dias", "Previous 7 days": "Últimos 7 dias", "Previous message": "Mensagem Anterior", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privado", "Private conversation between selected users": "Conversa privada entre utilizadores selecionados", "Production version updated": "Versão de produção atualizada", @@ -2189,7 +2220,8 @@ "Reset Vector Storage/Knowledge": "Repor Armazenamento de Vetores/Conhecimento", "Reset view": "Repor vista", "Response": "Resposta", - "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "As notificações de resposta não podem ser ativadas, pois as permissões do site foram negadas. Por favor, visite as configurações do seu navegador para conceder o acesso necessário.", + "Response Auto-Scroll": "", + "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "As notificações de resposta não podem ser ativadas, pois as permissões do site foram negadas. Por favor, visite as definições do seu navegador para conceder o acesso necessário.", "Response Splitting": "", "Response Watermark": "Marca d'água de Resposta", "Responses": "Respostas", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultado", "RESULT": "RESULTADO", + "Retained Messages": "", "Retrieval": "Recuperação", "Retrieval Query Generation": "Geração de Consulta de Recuperação", "Retrieved {{count}} sources": "Recuperadas {{count}} fontes", @@ -2236,12 +2269,13 @@ "Save Chat": "Guardar Conversa", "Saved": "Guardado", "Saved Memories": "", - "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Guardar o registo das conversas diretamente no armazenamento do seu navegador já não é suportado. Reserve um momento para descarregar e eliminar os seus registos de conversas clicando no botão abaixo. Não se preocupe, você pode facilmente reimportar os seus registos de conversas para o backend através de", + "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Guardar o registo das conversas diretamente no armazenamento do seu navegador já não é suportado. Reserve um momento para descarregar e eliminar os seus registos de conversas clicando no botão abaixo. Não se preocupe, pode facilmente reimportar os seus registos de conversas para o backend através de", "Saving...": "", "Schedule": "", "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Scroll na Mudança de Ramo", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Pesquisar", @@ -2258,6 +2292,7 @@ "Search Files": "Pesquisar Ficheiros", "Search filters": "", "Search Filters": "Pesquisar Filtros", + "Search folders": "", "search for archived chats": "pesquisar conversas arquivadas", "search for folders": "pesquisar pastas", "search for pinned chats": "pesquisar conversas fixadas", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "Modelo selecionado: {{modelName}}", "Selected model(s) do not support image inputs": "O(s) modelo(s) selecionado(s) não suporta(m) entradas de imagem", + "Selected models define incompatible Chat Variables.": "", "semantic": "semântico", "Send": "Enviar", "Send a Message": "Enviar uma Mensagem", @@ -2396,11 +2432,11 @@ "Sets how far back for the model to look back to prevent repetition.": "Define o quão longe para o modelo olhar para trás para evitar repetições.", "Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.": "Define a semente de número aleatório a ser usada para geração. Definir isso para um número específico fará com que o modelo gere o mesmo texto para o mesmo prompt.", "Sets the size of the context window used to generate the next token.": "Define o tamanho da janela de contexto usada para gerar o próximo token.", - "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Define as sequências de parada a serem usadas. Quando este padrão é encontrado, o LLM interromperá a geração de texto e retornará. Vários padrões de parada podem ser definidos especificando vários parâmetros de parada separados em um arquivo de modelo.", - "Setting": "Configuração", - "Settings": "Configurações", - "Settings Permissions": "Permissões de Configurações", - "Settings saved successfully!": "Configurações guardadas com sucesso!", + "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Define as sequências de parada a serem usadas. Quando este padrão é encontrado, o LLM interromperá a geração de texto e retornará. Vários padrões de parada podem ser definidos especificando vários parâmetros de parada separados num ficheiro de modelo.", + "Setting": "Definição", + "Settings": "Definições", + "Settings Permissions": "Permissões de Definições", + "Settings saved successfully!": "Definições guardadas com sucesso!", "Shapes the short label generated for each chat.": "", "Share": "Partilhar", "Share Chat": "Partilhar Conversa", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "Partilha Pública de Habilidades", "Skills Sharing": "Partilha de Habilidades", "Skip Cache": "Ignorar Cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Algo correu mal :/", "Sonar": "Sonar", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Passos", "Stop": "Parar", + "Stop camera": "", "Stop Download": "Parar Download", "Stop Generating": "Parar Geração", "Stop Sequence": "Sequência de Paragem", @@ -2509,7 +2547,7 @@ "Strikethrough": "Rasurado", "Strip Existing OCR": "Remover OCR Existente", "STT Model": "Modelo STT", - "STT Settings": "Configurações STT", + "STT Settings": "Definições STT", "Stylized PDF Export": "Exportação de PDF Estilizado", "Su_day_of_week": "", "Sub Claim": "", @@ -2530,6 +2568,7 @@ "Support": "Suporte", "Support this plugin:": "Suporte este plugin:", "Supported MIME Types": "Tipos MIME Suportados", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "Sincronizar", @@ -2552,7 +2591,7 @@ "Tags": "Etiquetas", "Tags Generation": "Geração de Etiquetas", "Tags Generation Prompt": "Prompt de Geração de Etiquetas", - "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "A amostragem tail free é usada para reduzir o impacto de tokens menos prováveis da saída. Um valor mais alto (por exemplo, 2.0) reduzirá mais o impacto, enquanto um valor de 1.0 desativa esta configuração.", + "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "A amostragem tail free é usada para reduzir o impacto de tokens menos prováveis da saída. Um valor mais alto (por exemplo, 2.0) reduzirá mais o impacto, enquanto um valor de 1.0 desativa esta definição.", "Talk to Model": "Falar com o Modelo", "Tap to interrupt": "Toque para interromper", "Target ID": "", @@ -2584,10 +2623,10 @@ "Text-to-Speech Engine": "Motor de Texto para Fala", "Th_day_of_week": "", "Thanks for your feedback!": "Obrigado pelo seu feedback!", - "The Application Account DN you bind with for search": "A DN de Conta de Aplicação que você vincula para pesquisa", + "The Application Account DN you bind with for search": "A DN de Conta de Aplicação que associa para a pesquisa", "The base to search for users": "A base para pesquisar utilizadores", "The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory.": "O tamanho do lote determina quantos pedidos de texto são processados juntos de uma vez. Um tamanho de lote maior pode aumentar o desempenho e a velocidade do modelo, mas também requer mais memória.", - "The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Os desenvolvedores por trás deste plugin são voluntários apaixonados da comunidade. Se você achar este plugin útil, considere contribuir para o seu desenvolvimento.", + "The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Os programadores por trás deste plugin são voluntários apaixonados da comunidade. Se considerar este plugin útil, pondere contribuir para o seu desenvolvimento.", "The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "O quadro de líderes de avaliação é baseado no sistema de classificação Elo e é atualizado em tempo real.", "The format to return a response in. Format can be json or a JSON schema.": "O formato para retornar uma resposta. O formato pode ser json ou um esquema JSON.", "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.": "O idioma do áudio de entrada. Fornecer o idioma de entrada no formato ISO-639-1 (por exemplo, en) melhorará a precisão e a latência. Deixe em branco para detectar automaticamente o idioma.", @@ -2604,7 +2643,7 @@ "Thinking...": "A pensar...", "This action cannot be undone. Do you wish to continue?": "Esta ação não pode ser desfeita. Deseja continuar?", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Este canal foi criado em {{createdAt}}. Este é o início do canal {{channelName}}.", - "This chat won't appear in history and your messages will not be saved.": "Esta conversa não aparecerá no histórico e suas mensagens não serão salvas.", + "This chat won't appear in history and your messages will not be saved.": "Esta conversa não aparecerá no histórico e as suas mensagens não serão guardadas.", "This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Isto garante que suas conversas valiosas sejam guardadas com segurança na sua base de dados de backend. Obrigado!", "This folder is empty": "Esta pasta está vazia", "This is a default user permission and will remain enabled.": "Esta é uma permissão de utilizador padrão e permanecerá ativada.", @@ -2617,9 +2656,9 @@ "This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated.": "Esta opção define o número máximo de tokens que o modelo pode gerar em sua resposta. Aumentar esse limite permite que o modelo forneça respostas mais longas, mas também pode aumentar a probabilidade de conteúdo inútil ou irrelevante ser gerado.", "This response was generated by \"{{model}}\"": "Esta resposta foi gerada por \"{{model}}\"", "This template contains multiple context placeholders ([context] or {{CONTEXT}}). Context will be injected at each occurrence.": "", - "This will delete": "Isto irá excluir", - "This will delete {{NAME}} and all its contents.": "Isto irá excluir {{NAME}} e todo o seu conteúdo.", - "This will delete all models including custom models and cannot be undone.": "Isto irá excluir todos os modelos, incluindo os modelos personalizados, e não pode ser desfeito.", + "This will delete": "Isto irá eliminar", + "This will delete {{NAME}} and all its contents.": "Isto irá eliminar {{NAME}} e todo o seu conteúdo.", + "This will delete all models including custom models and cannot be undone.": "Isto irá eliminar todos os modelos, incluindo os modelos personalizados, e não pode ser desfeito.", "This will permanently delete the calendar \"{{name}}\" and all its events. This action cannot be undone.": "", "This will remove all files and directories from this knowledge base. This action cannot be undone.": "", "Thorough explanation": "Explicação Minuciosa", @@ -2669,7 +2708,7 @@ "Toggle Mute": "", "Toggle Sidebar": "Alternar Barra Lateral", "Toggle status history": "Alternar histórico de status", - "Toggle whether current connection is active.": "Alternar se a conexão atual está ativa.", + "Toggle whether current connection is active.": "Alternar se a ligação atual está ativa.", "Token": "Token", "Token activity": "", "Token Cap": "", @@ -2695,8 +2734,8 @@ "Tools can execute arbitrary code.": "", "Tools Function Calling Prompt": "Prompt de Chamada de Funções das Ferramentas", "Tools have a function calling system that allows arbitrary code execution.": "As ferramentas possuem um sistema de chamada de funções que permite a execução de código arbitrário.", - "Tools Public Sharing": "Compartilhamento Público de Ferramentas", - "Tools Sharing": "Compartilhamento de Ferramentas", + "Tools Public Sharing": "Partilha Pública de Ferramentas", + "Tools Sharing": "Partilha de Ferramentas", "Top": "Topo", "Top K": "Top K", "Top K Reranker": "Reranker Top K", @@ -2708,7 +2747,7 @@ "Try adjusting your search or filter to find what you are looking for.": "Tente ajustar sua pesquisa ou filtro para encontrar o que está a procurar.", "Try Again": "Tente outra vez", "TTS Model": "Modelo TTS", - "TTS Settings": "Configurações TTS", + "TTS Settings": "Definições TTS", "TTS Voice": "Voz TTS", "Tu_day_of_week": "", "Type": "Tipo", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "Desafixar", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Parar partilha de conversa", @@ -2735,13 +2775,14 @@ "Untagged": "Desafixado", "Untitled": "Sem título", "Update": "Atualizar", + "Update All Models": "", "Update and Copy Link": "Atualizar e Copiar Link", "Update Email": "", "Update embedding model": "", "Update for the latest features and improvements.": "Atualize para os recursos e melhorias mais recentes.", "Update model": "", "Update Name": "", - "Update password": "Atualizar senha", + "Update password": "Atualizar palavra-passe", "Update Picture": "", "Update the password used for email and password sign-in.": "", "Update your status": "Atualize seu status", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "utilizador", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Avaliações do Utilizador (positivo/negativo)", "User Status": "Estado do Utilizador", + "User Variables": "", "User Webhooks": "Webhooks do Utilizador", "Username": "Nome de Utilizador", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Válvulas", "Valves updated": "Válvulas atualizadas", "Valves updated successfully": "Válvulas atualizadas com sucesso", "variable": "variável", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Verificar Ligação", "Verify SSL Certificate": "Verificar Certificado SSL", @@ -2870,7 +2918,7 @@ "Webhook saved": "", "Webhooks": "Webhooks", "Webpage URLs": "URLs de Páginas Web", - "WebUI Settings": "Configurações WebUI", + "WebUI Settings": "Definições WebUI", "WebUI URL": "URL do WebUI", "WebUI will make requests to \"{{url}}\"": "O WebUI fará solicitações para \"{{url}}\"", "WebUI will make requests to \"{{url}}/api/chat\"": "O WebUI fará solicitações para \"{{url}}/api/chat\"", @@ -2880,10 +2928,10 @@ "Weekly": "", "Weekly at": "", "Welcome to your AI home.": "", - "What are you trying to achieve?": "O que você está tentando alcançar?", - "What are you working on?": "Em que você está trabalhando?", - "What is NOT shared:": "O que NÃO é compartilhado:", - "What is shared:": "O que é compartilhado:", + "What are you trying to achieve?": "O que está a tentar alcançar?", + "What are you working on?": "Em que está a trabalhar?", + "What is NOT shared:": "O que NÃO é partilhado:", + "What is shared:": "O que é partilhado:", "What's New in": "O que há de novo em", "What's on your mind?": "O que está A pensaR?", "When": "", @@ -2906,8 +2954,8 @@ "Write something...": "Escreva algo...", "Write your model system prompt content here\ne.g.) You are Mario from Super Mario Bros, acting as an assistant.": "Escreva aqui o conteúdo do system prompt do seu modelo\np. ex.: É o Mario do Super Mario Bros e atua como assistente.", "Yacy Instance URL": "URL da Instância Yacy", - "Yacy Password": "Senha Yacy", - "Yacy Username": "Nome de Usuário Yacy", + "Yacy Password": "Palavra-passe Yacy", + "Yacy Username": "Nome de Utilizador Yacy", "Yahoo": "Yahoo", "Yandex": "Yandex", "Yandex Web Search API Key": "Chave API de Pesquisa Web Yandex", @@ -2919,7 +2967,7 @@ "You are a sub-agent...": "", "You are currently using a trial license. Please contact support to upgrade your license.": "Está atualmente a utilizar uma licença de teste. Por favor, contacte o suporte para atualizar a sua licença.", "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Só pode conversar com um máximo de {{maxCount}} ficheiro(s) de cada vez.", - "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pode personalizar as suas interações com LLMs adicionando memórias através do botão 'Gerir' abaixo, tornando-as mais úteis e personalizadas para você.", + "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pode personalizar as suas interações com LLMs adicionando memórias através do botão 'Gerir' abaixo, tornando-as mais úteis e personalizadas para si.", "You cannot upload an empty file.": "Não pode enviar um ficheiro vazio.", "You do not have permission to edit this model": "Não tem permissão para editar este modelo", "You do not have permission to edit this prompt.": "Não tem permissão para editar este prompt.", @@ -2941,7 +2989,7 @@ "Your account status is currently pending activation.": "O status da sua conta está atualmente com a ativação pendente.", "Your browser does not support the audio tag.": "O seu navegador não suporta a tag de áudio.", "Your browser does not support the video tag.": "O seu navegador não suporta a tag de vídeo.", - "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "A sua contribuição irá diretamente para o desenvolvedor do plugin; o Open WebUI não recebe nenhuma percentagem. No entanto, a plataforma de financiamento escolhida pode ter as suas próprias taxas.", + "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "A sua contribuição irá diretamente para o programador do plugin; o Open WebUI não recebe nenhuma percentagem. No entanto, a plataforma de financiamento escolhida pode ter as suas próprias taxas.", "Your message text or inputs": "O texto da sua mensagem ou entradas", "Your query will be sent to the configured web search provider.": "", "Your usage stats have been successfully synced.": "As suas estatísticas de uso foram sincronizadas com sucesso.", diff --git a/src/lib/i18n/locales/ro-RO/translation.json b/src/lib/i18n/locales/ro-RO/translation.json index a2c9d94e38..27c07cb4a4 100644 --- a/src/lib/i18n/locales/ro-RO/translation.json +++ b/src/lib/i18n/locales/ro-RO/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Adaugă utilizator", "Add User Group": "Adaugă grup de utilizatori", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Permite localizarea utilizatorului", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "și creează un nou link partajat.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL Bază API", "API Key": "Cheie API", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "Generare automată a etichetelor de conversație", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Conversații", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Verifică din Nou", "Check for updates": "Verifică actualizări", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Alege un model înainte de a salva...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Șterge memoria", "Clear Memory": "Golește memoria", @@ -571,6 +580,7 @@ "Confirm": "Confirmă", "Confirm Password": "Confirmă Parola", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Confirmă acțiunea ta", "Confirm your new password": "", "Confirm Your Password": "", @@ -727,6 +737,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Rolul Implicit al Utilizatorului", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Nu a urmat complet instrucțiunile", "Direct": "", @@ -846,6 +858,7 @@ "Download as SVG": "", "Download canceled": "Descărcare anulată", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Editează Utilizator", "Edit User Group": "Editează grupul de utilizatori", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Activat", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Nu s-a putut salva conversația", "Failed to save models configuration": "", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1299,6 +1316,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Cunoștințe", "Knowledge Access": "", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Ascult...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM-urile pot face greșeli. Verificați informațiile importante.", "Loaded": "", "Loader": "", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Martie", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Modelul '{{modelName}}' a fost descărcat cu succes.", "Model '{{modelTag}}' is already in queue for downloading.": "Modelul '{{modelTag}}' este deja în coada de descărcare.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Modelul {{modelName}} nu are capacități de viziune", "Model {{name}} is now {{status}}": "Modelul {{name}} este acum {{status}}", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "Nu există valve de actualizat", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ups! Încă mai există fișiere care se încarcă. Vă rugăm să așteptați până se finalizează încărcarea.", "Oops! There was an error in the previous response.": "Ups! A apărut o eroare în răspunsul anterior.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! Utilizați o metodă nesuportată (doar frontend). Vă rugăm să serviți WebUI din backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Permisiunea refuzată la accesarea dispozitivelor media", "Permission denied when accessing microphone": "Permisiunea refuzată la accesarea microfonului", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Ultimele 30 de zile", "Previous 7 days": "Ultimele 7 zile", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "Resetarea Stocării/Vectoului de Cunoștințe", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Notificările de răspuns nu pot fi activate deoarece permisiunile site-ului au fost refuzate. Vă rugăm să vizitați setările browserului pentru a acorda accesul necesar.", "Response Splitting": "", "Response Watermark": "", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Rezultat", "RESULT": "Rezultat", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Caută", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Modelul(e) selectat(e) nu suportă intrări de imagine", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Trimite", "Send a Message": "Trimite un Mesaj", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Oprire", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Oprește Secvența", @@ -2530,6 +2568,7 @@ "Support": "Suport", "Support this plugin:": "Susține acest plugin:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "Anulează Fixarea", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "Netichetat", "Untitled": "", "Update": "Actualizează", + "Update All Models": "", "Update and Copy Link": "Actualizează și Copiază Link-ul", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "utilizator", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valve", "Valves updated": "Valve actualizate", "Valves updated successfully": "Valve actualizate cu succes", "variable": "variabilă", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/ru-RU/translation.json b/src/lib/i18n/locales/ru-RU/translation.json index eb9b83f61c..bd8edeff1b 100644 --- a/src/lib/i18n/locales/ru-RU/translation.json +++ b/src/lib/i18n/locales/ru-RU/translation.json @@ -131,6 +131,7 @@ "Add to favorites": "Добавить в избранное", "Add User": "Добавить пользователя", "Add User Group": "Добавить группу пользователей", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Добавить веб-страницу", "Add your Open Terminal URL and API key in Settings → Integrations.": "Добавьте URL и API-ключ Open Terminal в Настройки → Интеграции.", @@ -204,6 +205,7 @@ "Allow User Location": "Разрешить доступ к местоположению пользователя", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -237,6 +239,7 @@ "and create a new shared link.": "и создайте новую общую ссылку.", "Android": "Android", "Anyone": "Кому угодно", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Базовый адрес API", "API Key": "Ключ API", @@ -302,6 +305,7 @@ "At time of event": "В момент события", "Attach File From Knowledge": "Прикрепить файл из знаний", "Attach Files": "Прикрепить файлы", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Прикрепить знания", "Attach Notes": "Прикрепить заметки", "Attach Webpage": "Прикрепить веб-страницу", @@ -444,8 +448,11 @@ "Chat Permissions": "Разрешения для чата", "Chat Tags Auto-Generation": "Автогенерация тегов чата", "Chat unshared successfully.": "Общий доступ к чату отключен.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "чаты", "Chats": "Чаты", + "Chats Open Sharing": "", "Chats Public Sharing": "Публичный доступ к чатам", "Check Again": "Перепроверьте ещё раз", "Check for updates": "Проверить обновления", @@ -453,6 +460,7 @@ "Choose a model before saving...": "Выберите модель перед сохранением...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -486,6 +494,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Очистить воспоминания", "Clear Memory": "Очистить память", @@ -579,6 +588,7 @@ "Confirm": "Подтвердить", "Confirm Password": "Подтвердите пароль", "Confirm Prompt from Embed": "Подтвердите запрос из встроенного виджета", + "Confirm recording": "", "Confirm your action": "Подтвердите свое действие", "Confirm your new password": "Подтвердите свой новый пароль", "Confirm Your Password": "Подтвердите свой пароль", @@ -735,6 +745,7 @@ "Default to ALL": "По умолчанию ВСЕ", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "По умолчанию используется сегментированный поиск для целенаправленного извлечения релевантного контента, что рекомендуется в большинстве случаев.", + "Default Upload Mode": "", "Default User Role": "Роль пользователя по умолчанию", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -783,6 +794,7 @@ "Deselect": "Снять выделение", "Detect Artifacts Automatically": "Автоматическое обнаружение артефактов", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Диктовать", "Didn't fully follow instructions": "Не полностью следует инструкциям", "Direct": "Прямое", @@ -854,6 +866,7 @@ "Download as SVG": "Загрузить как SVG", "Download canceled": "Загрузка отменена", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -901,6 +914,7 @@ "Edit Terminal Connection": "Редактировать подключение к терминалу", "Edit User": "Редактировать пользователя", "Edit User Group": "Редактировать Пользовательскую Группу", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Редактировать содержимое workflow.json", "edited": "изменено", @@ -934,6 +948,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Включить, отключить или настроить теги рассуждения, используемые моделью. \"Включено\" использует теги по умолчанию, \"Отключено\" выключает теги рассуждения, а \"Пользовательские\" позволяет указать собственные начальные и конечные теги.", "Enabled": "Включено", + "End call": "", "End Tag": "Конечный тег", "Endpoint": "", "Endpoint URL": "URL-адрес конечной точки", @@ -1195,6 +1210,7 @@ "Failed to remove member": "Не удалось удалить участника", "Failed to render diagram": "Не удалось отрисовать диаграмму", "Failed to render visualization": "Не удалось отрисовать визуализацию", + "Failed to save chat variables": "", "Failed to save connections": "Не удалось сохранить подключения", "Failed to save conversation": "Не удалось сохранить беседу", "Failed to save models configuration": "Не удалось сохранить конфигурацию моделей", @@ -1262,6 +1278,7 @@ "Folder updated successfully": "Папка успешно обновлена", "Folders": "Папки", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Продолжить", "Follow Up Generation": "Генерация продолжения", "Follow Up Generation Prompt": "Промпт генерации продолжения", @@ -1309,6 +1326,7 @@ "Generate an image": "Сгенерировать изображение", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Генерация и редактирование изображений", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Сгенерировать пару сообщений", "Generate suggested follow-up prompts after responses.": "", @@ -1487,6 +1505,7 @@ "Keep in Sidebar": "Оставить на боковой панели", "Key": "Ключ", "Key is required": "Ключ обязателен", + "key_name": "", "Keyboard": "", "Knowledge": "Знания", "Knowledge Access": "Доступ к знаниям", @@ -1560,9 +1579,9 @@ "List": "Список", "List calendars, search, create, update, and delete calendar events": "Просматривайте календари, ищите, создавайте, обновляйте и удаляйте события календаря", "Listening...": "Слушаю...", + "LiteLLM": "", "Live": "Активно", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs могут допускать ошибки. Проверяйте важную информацию.", "Loaded": "Загружено", "Loader": "Загрузчик", @@ -1601,6 +1620,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Март", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Разделение текста по заголовкам Markdown", "Max background": "", @@ -1673,7 +1694,6 @@ "Model": "Модель", "Model '{{modelName}}' has been successfully downloaded.": "Модель '{{modelName}}' успешно загружена.", "Model '{{modelTag}}' is already in queue for downloading.": "Модель '{{modelTag}}' уже находится в очереди на загрузку.", - "Model {{modelId}} not found": "Модель {{modelId}} не найдена", "Model {{modelName}} deleted successfully": "Модель {{modelName}} успешно удалена", "Model {{modelName}} is not vision capable": "Модель {{modelName}} не поддерживает зрение", "Model {{name}} is now {{status}}": "Модель {{name}} теперь {{status}}", @@ -1772,8 +1792,11 @@ "New Webhook": "Новый вебхук", "new-channel": "new-channel", "Next message": "Следующее сообщение", + "Next month": "", "Next page": "", "Next run": "Следующий запуск", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Нет прав доступа. Доступно только вам.", "No actions found": "", "No activity data": "Нет данных об активности", @@ -1804,6 +1827,7 @@ "No files in this knowledge base.": "В этой базе знаний нет файлов.", "No files yet. Upload files or run Python code to create them.": "Файлов пока нет. Загрузите файлы или создайте их с помощью Python.", "No filters found": "", + "No folders": "", "No functions found": "Функции не найдены", "No groups found": "Группы не найдены", "No history available": "История недоступна", @@ -1845,6 +1869,7 @@ "No tools accessible": "", "No tools found": "Инструменты не найдены", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Пользователи не найдены.", "No valves": "Нет параметров", "No valves to update": "Нет параметров для обновления", @@ -1916,6 +1941,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Упс! Есть файлы, которые все еще загружаются. Пожалуйста, дождитесь завершения загрузки.", "Oops! There was an error in the previous response.": "Упс! В предыдущем ответе была ошибка.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Упс! Вы используете неподдерживаемый метод (только фронтенд). Пожалуйста, обслуживайте веб-интерфейс из бэкенда.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1993,6 +2019,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Содержимое оверлея ожидающего пользователя", "Pending User Overlay Title": "Заголовк оверлея ожидающего пользователя", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Отказано в разрешении на доступ к мультимедийным устройствам", "Permission denied when accessing microphone": "Отказано в разрешении на доступ к микрофону", @@ -2056,6 +2083,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID префикса", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "ID префикса используется для предотвращения конфликтов с другими подключениями путем добавления префикса к идентификаторам моделей - оставьте пустым, чтобы отключить", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Запретить создание файлов", "Preview": "Предпросмотр", @@ -2063,7 +2091,10 @@ "Previous 30 days": "Предыдущие 30 дней", "Previous 7 days": "Предыдущие 7 дней", "Previous message": "Предыдущее сообщение", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Частное", "Private conversation between selected users": "Личная беседа между выбранными пользователями", "Production version updated": "Рабочая версия обновлена", @@ -2201,6 +2232,7 @@ "Reset Vector Storage/Knowledge": "Сброс векторного хранилища/знаний", "Reset view": "Сбросить вид", "Response": "Ответ", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Уведомления об ответах не могут быть активированы, поскольку доступ к веб-сайту был заблокирован. Пожалуйста, перейдите к настройкам своего браузера, чтобы предоставить необходимый доступ.", "Response Splitting": "", "Response Watermark": "Водяной знак ответа", @@ -2209,6 +2241,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Результат", "RESULT": "Результат", + "Retained Messages": "", "Retrieval": "Поиск", "Retrieval Query Generation": "Генерация поискового запроса", "Retrieved {{count}} sources": "Найдено {{count}} источников", @@ -2255,6 +2288,7 @@ "Scheduled time must be in the future": "Запланированное время должно быть в будущем", "Scopes": "", "Scroll On Branch Change": "Прокручивать при изменении ветки", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Прокрутить наверх", "Search": "Поиск", @@ -2271,6 +2305,7 @@ "Search Files": "Поиск файлов", "Search filters": "", "Search Filters": "Поиск фильтров", + "Search folders": "", "search for archived chats": "поиск архивных чатов", "search for folders": "поиск папок", "search for pinned chats": "поиск закреплённых чатов", @@ -2356,6 +2391,7 @@ "Selected": "", "Selected model: {{modelName}}": "Выбранная модель: {{modelName}}", "Selected model(s) do not support image inputs": "Выбранные модели не поддерживают ввод изображений", + "Selected models define incompatible Chat Variables.": "", "semantic": "семантический", "Send": "Отправить", "Send a Message": "Отправить сообщение", @@ -2476,6 +2512,7 @@ "Skills Public Sharing": "Публичный доступ к скиллам", "Skills Sharing": "Общий доступ к скиллам", "Skip Cache": "Пропустить кэширование", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Что-то пошло не так :/", "Sonar": "Sonar", @@ -2513,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Шаги", "Stop": "Остановить", + "Stop camera": "", "Stop Download": "Остановить загрузку", "Stop Generating": "Остановить генерацию", "Stop Sequence": "Последовательность останова", @@ -2544,6 +2582,7 @@ "Support": "Поддержать", "Support this plugin:": "Поддержите этот плагин", "Supported MIME Types": "Поддерживаемые MIME типы", + "Switch camera": "", "Switch to JSON editor": "Переключиться на редактор JSON", "Switch to visual editor": "Переключиться на визуальный редактор", "Sync": "Синхронизация", @@ -2742,6 +2781,7 @@ "Unmute": "Включить микрофон", "Unpin": "Открепить", "Unpin from Sidebar": "Открепить от боковой панели", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Отменить публикацию чата", @@ -2749,6 +2789,7 @@ "Untagged": "Без тегов", "Untitled": "Без заголовка", "Update": "Обновить", + "Update All Models": "", "Update and Copy Link": "Обновить и скопировать ссылку", "Update Email": "", "Update embedding model": "", @@ -2806,6 +2847,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "пользователь", @@ -2820,6 +2862,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Оценки пользователей (нравится/не нравится)", "User Status": "Статус пользователя", + "User Variables": "", "User Webhooks": "Пользовательские веб-хуки", "Username": "Имя пользователя", "Username Claim": "", @@ -2834,10 +2877,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Параметры", "Valves updated": "Параметры обновлены", "Valves updated successfully": "Параметры успешно обновлены", "variable": "переменная", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Проверить подключение", "Verify SSL Certificate": "Проверять SSL-сертификат", diff --git a/src/lib/i18n/locales/sk-SK/translation.json b/src/lib/i18n/locales/sk-SK/translation.json index a1f6eccf82..73cf2e486b 100644 --- a/src/lib/i18n/locales/sk-SK/translation.json +++ b/src/lib/i18n/locales/sk-SK/translation.json @@ -131,6 +131,7 @@ "Add to favorites": "", "Add User": "Pridať užívateľa", "Add User Group": "Pridať skupinu užívateľov", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -204,6 +205,7 @@ "Allow User Location": "Povoliť užívateľskú polohu", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -237,6 +239,7 @@ "and create a new shared link.": "a vytvoriť nový zdieľaný odkaz.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Základná URL adresa API", "API Key": "API kľúč", @@ -302,6 +305,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Pripojiť znalosti", "Attach Notes": "Pripojiť poznámky", "Attach Webpage": "Pripojiť webovú stránku", @@ -444,8 +448,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "Automatické generovanie značiek chatu", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chaty", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Skontroluj znovu", "Check for updates": "Skontrolovať aktualizácie", @@ -453,6 +460,7 @@ "Choose a model before saving...": "Vyberte model pred uložením...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -486,6 +494,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Vymazať pamäť", "Clear Memory": "", @@ -579,6 +588,7 @@ "Confirm": "Potvrdiť", "Confirm Password": "Potvrdenie hesla", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Potvrďte svoju akciu", "Confirm your new password": "", "Confirm Your Password": "", @@ -735,6 +745,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Predvolená rola užívateľa", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -783,6 +794,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktovať", "Didn't fully follow instructions": "Nenasledovali ste presne všetky inštrukcie.", "Direct": "", @@ -854,6 +866,7 @@ "Download as SVG": "", "Download canceled": "Sťahovanie zrušené", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -901,6 +914,7 @@ "Edit Terminal Connection": "", "Edit User": "Upraviť užívateľa", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "upravené", @@ -934,6 +948,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Povolené", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1195,6 +1210,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Nepodarilo sa uložiť konverzáciu", "Failed to save models configuration": "", @@ -1262,6 +1278,7 @@ "Folder updated successfully": "Priečinok bol úspešne aktualizovaný.", "Folders": "Priečinky", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Doplňujúce otázky", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1309,6 +1326,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1487,6 +1505,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Znalosti", "Knowledge Access": "", @@ -1560,9 +1579,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Počúvanie...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM môžu robiť chyby. Overte si dôležité informácie.", "Loaded": "", "Loader": "", @@ -1601,6 +1620,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Marec", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1673,7 +1694,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model „{{modelName}}“ bol úspešne stiahnutý.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' je už zaradený do fronty na sťahovanie.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} nie je schopný spracovávať vizuálne údaje.", "Model {{name}} is now {{status}}": "Model {{name}} je teraz {{status}}.", @@ -1772,8 +1792,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1804,6 +1827,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1845,6 +1869,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "Žiadne ventily na aktualizáciu", @@ -1916,6 +1941,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Jejda! Niektoré súbory sa stále nahrávajú. Prosím, počkajte, kým sa nahrávanie dokončí.", "Oops! There was an error in the previous response.": "Jejda! V predchádzajúcej odpovedi došlo k chybe.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Jejda! Používate nepodporovanú metódu (iba frontend). Prosím, spustite WebUI zo serverovej časti (backendu).", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1993,6 +2019,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Odmietnutie povolenia pri prístupe k mediálnym zariadeniam", "Permission denied when accessing microphone": "Prístup k mikrofónu bol zamietnutý", @@ -2056,6 +2083,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2063,7 +2091,10 @@ "Previous 30 days": "Predchádzajúcich 30 dní", "Previous 7 days": "Predchádzajúcich 7 dní", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Súkromné", "Private conversation between selected users": "", "Production version updated": "", @@ -2201,6 +2232,7 @@ "Reset Vector Storage/Knowledge": "Resetovanie úložiska vektorov/znalostí", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Oznámenia o odpovediach nie je možné aktivovať, pretože povolenia webu boli zamietnuté. Navštívte nastavenia svojho prehliadača a povoľte potrebný prístup.", "Response Splitting": "", "Response Watermark": "", @@ -2209,6 +2241,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Výsledok", "RESULT": "Výsledok", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2255,6 +2288,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Vyhľadávanie", @@ -2271,6 +2305,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2356,6 +2391,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Vybraný(é) model(y) nepodporujú vstupy v podobe obrázkov.", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Odoslať", "Send a Message": "Odoslať správu", @@ -2476,6 +2512,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2513,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Zastaviť", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Sekvencia zastavenia", @@ -2544,6 +2582,7 @@ "Support": "Podpora", "Support this plugin:": "Podporte tento plugin:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2742,6 +2781,7 @@ "Unmute": "", "Unpin": "Odopnúť", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2749,6 +2789,7 @@ "Untagged": "Nebola označená", "Untitled": "", "Update": "Aktualizovať", + "Update All Models": "", "Update and Copy Link": "Aktualizovať a skopírovať odkaz", "Update Email": "", "Update embedding model": "", @@ -2806,6 +2847,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "používateľ", @@ -2820,6 +2862,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Používateľské meno", "Username Claim": "", @@ -2834,10 +2877,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Ventily", "Valves updated": "Ventily aktualizované", "Valves updated successfully": "Ventily boli úspešne aktualizované.", "variable": "premenná", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/sl-SI/translation.json b/src/lib/i18n/locales/sl-SI/translation.json index e31ad590a6..9493a3ef77 100644 --- a/src/lib/i18n/locales/sl-SI/translation.json +++ b/src/lib/i18n/locales/sl-SI/translation.json @@ -1,8 +1,5 @@ { "-1 for no limit, or a positive integer for a specific limit": "-1 za brez omejitve ali pozitivno celo število za določeno omejitev", - "'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' ali '-1' za brez poteka.", - "(e.g. `sh webui.sh --api --api-auth username_password`)": "(e.g. `sh webui.sh --api --api-auth username_password`)", - "(e.g. `sh webui.sh --api`)": "(e.g. `sh webui.sh --api`)", "(latest)": "(najnovejše)", "(leave blank for to use commercial endpoint)": "(pustite prazno za uporabo komercialne končne točke)", "[Last] dddd [at] h:mm A": "[Prejšnji] dddd [ob] H:mm", @@ -13,23 +10,39 @@ "{{COUNT}} Available Tools": "{{COUNT}} Available orodja", "{{COUNT}} characters": "{{COUNT}} characters", "{{COUNT}} extracted lines": "{{COUNT}} extracted lines", + "{{count}} files_one": "", + "{{count}} files_two": "", + "{{count}} files_few": "", + "{{count}} files_other": "", "{{COUNT}} files": "{{COUNT}} datoteke", "{{count}} files selected. Only new and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?_one": "{{count}} files selected. Only nov and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?", + "{{count}} files selected. Only new and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?_two": "", + "{{count}} files selected. Only new and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?_few": "", "{{count}} files selected. Only new and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?_other": "{{count}} files selected. Only nov and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?", "{{count}} filters_one": "{{count}} filtri", + "{{count}} filters_two": "", + "{{count}} filters_few": "", "{{count}} filters_other": "{{count}} filtri", "{{count}} groups_one": "{{count}} skupine", + "{{count}} groups_two": "", + "{{count}} groups_few": "", "{{count}} groups_other": "{{count}} skupine", "{{COUNT}} hidden lines": "{{COUNT}} hidden lines", "{{COUNT}} members": "{{COUNT}} members", "{{count}} of {{total}} accessible_one": "{{count}} of {{total}} accessible", + "{{count}} of {{total}} accessible_two": "", + "{{count}} of {{total}} accessible_few": "", "{{count}} of {{total}} accessible_other": "{{count}} of {{total}} accessible", "{{COUNT}} Replies": "{{COUNT}} Replies", "{{COUNT}} Rows": "{{COUNT}} Rows", "{{count}} selected_one": "{{count}} selected", + "{{count}} selected_two": "", + "{{count}} selected_few": "", "{{count}} selected_other": "{{count}} selected", "{{COUNT}} Sources": "{{COUNT}} viri", "{{count}} users_one": "{{count}} uporabniki", + "{{count}} users_two": "", + "{{count}} users_few": "", "{{count}} users_other": "{{count}} uporabniki", "{{COUNT}} words": "{{COUNT}} words", "{{COUNT}}d_time_ago": "pred {{COUNT}} d", @@ -39,13 +52,13 @@ "{{COUNT}}y_time_ago": "pred {{COUNT}} l", "{{label}} contains invalid JSON": "{{label}} contains invalid JSON", "{{label}} must be a JSON object": "{{label}} must be a JSON object", - "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}", "{{model}} download has been canceled": "{{model}} download has been canceled", "{{modelName}} profile image": "{{modelName}} profile image", "{{NAMES}} reacted with {{REACTION}}": "{{NAMES}} reacted with {{REACTION}}", "{{user}}'s Chats": "{{user}}'s Chats", "{{webUIName}} Backend Required": "{{webUIName}} Backend Required", "*Prompt node ID(s) are required for image generation": "*Prompt node ID(s) are required for image generation", + "1 file": "", "1 group": "1 skupina", "1 hour before": "1 uro prej", "1 Source": "1 vir", @@ -59,13 +72,13 @@ "A discussion channel where access is controlled by groups and permissions": "A discussion channel where access is controlled by groups and permissions", "A new version (v{{LATEST_VERSION}}) is now available.": "A new version (v{{LATEST_VERSION}}) is now available.", "A private conversation between you and selected users": "A private conversation between you and selected users", - "A task model is used when performing tasks such as generating titles for chats and web search queries": "A task model is used when performing tasks such as generating titles for chats and web search queries", "a user": "a user", "About": "O aplikaciji", "Accept Autocomplete Generation\nJump to Prompt Variable": "Sprejmi samodejno dopolnitev\nSkoči na spremenljivko poziva", "Access": "Dostop", "Access Control": "Nadzor dostopa", "Access Grants": "Dodeljeni dostopi", + "Access level": "", "Access List": "Seznam dostopa", "Access prohibited": "Dostop je prepovedan", "Access updated": "Dostop je posodobljen", @@ -76,11 +89,11 @@ "Action": "Dejanje", "Action Required for Chat Log Storage": "Potrebno je dejanje za shranjevanje dnevnika pogovorov", "Actions": "Dejanja", - "Activate": "Aktiviraj", "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Activate this command by typing \"/{{COMMAND}}\" to chat input.", "Active": "Aktivno", "Active Users": "Aktivni uporabniki", "Activity": "Dejavnost", + "Activity insights": "", "Add": "Dodaj", "Add a model ID": "Dodaj a model ID", "Add a preference, fact, or instruction about you": "Dodaj a preference, fact, or instruction about you", @@ -89,6 +102,7 @@ "Add a tag...": "Dodaj a tag...", "Add Access": "Dodaj dostop", "Add Arena Model": "Dodaj model arene", + "Add banner": "", "Add Connection": "Dodaj povezavo", "Add Content": "Dodaj vsebino", "Add content here": "Tukaj dodajte vsebino", @@ -97,6 +111,7 @@ "Add description": "Dodaj opis", "Add Details": "Dodaj podrobnosti", "Add durable context for future chats": "Dodaj durable context for future chats", + "Add filenames, titles, sections, and snippets to improve lexical recall.": "", "Add Files": "Dodaj datoteke", "Add Image": "Dodaj sliko", "Add Knowledge Connection": "Dodaj povezavo z bazo znanja", @@ -104,7 +119,9 @@ "Add Member": "Dodaj člana", "Add Members": "Dodaj člane", "Add Memory": "Dodaj pomnilnik", - "Add Model": "Dodaj model", + "Add Notification Target": "", + "Add optional profile context visible where profiles are shown.": "", + "Add prompt suggestion": "", "Add Reaction": "Dodaj odziv", "Add tag": "Dodaj oznako", "Add Tag": "Dodaj oznako", @@ -114,30 +131,32 @@ "Add to favorites": "Dodaj med priljubljene", "Add User": "Dodaj uporabnika", "Add User Group": "Dodaj skupino uporabnikov", + "Add User Variable": "", "Add webhook": "Dodaj webhook", "Add webpage": "Dodaj spletno stran", "Add your Open Terminal URL and API key in Settings → Integrations.": "Dodaj your Open terminal URL and API key in nastavitve → Integrations.", "Additional Config": "Dodatna konfiguracija", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level", + "Additional Docling parameters in JSON format.": "", "Additional feedback comments": "Dodatni komentarji povratnih informacij", + "Additional JSON headers sent to the external document loader.": "", "Additional Parameters": "Dodatni parametri", - "Adds filenames, titles, sections, and snippets into the BM25 text to improve lexical recall.": "Adds filenames, titles, sections, and snippets into the BM25 text to improve lexical recall.", - "Adjusting these settings will apply changes universally to all users.": "Spremembe teh nastavitev bodo veljale za vse uporabnike.", + "Adjust how quickly spoken responses are played.": "", "admin": "skrbnik", "Admin": "Skrbnik", "Admin Contact Email": "E-pošta skrbnika za stik", + "Admin Details": "", "Admin Panel": "Skrbniška plošča", "Admin Roles": "Skrbniške vloge", - "Admin Settings": "Skrbniške nastavitve", "Admin-managed service account": "Admin-managed service account", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Admins have access to all tools at all times; users need tools assigned per model in the workspace.", "Advanced": "Napredno", + "Advanced MinerU parsing parameters in JSON format.": "", "Advanced Parameters": "Napredni parametri", - "Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)": "Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)", "Advanced Params": "Napredni parametri", - "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.": "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.", - "AI": "AI", + "After changing the embedding model, reindex the knowledge base for changes to take effect.": "", "All": "Vse", + "All Chats": "", "All chats have been unarchived.": "All chats have been unarchived.", "All day": "Ves dan", "All events": "Vsi dogodki", @@ -149,6 +168,9 @@ "All time": "Ves čas", "All Users": "Vsi uporabniki", "All users and system events": "All users and system events", + "Allow artifacts to access same-origin browser APIs inside the sandbox.": "", + "Allow automatic names for new chats.": "", + "Allow browser notifications for completed responses.": "", "Allow Call": "Dovoli klic", "Allow Chat Controls": "Dovoli nadzor pogovora", "Allow Chat Delete": "Dovoli brisanje pogovorov", @@ -160,31 +182,54 @@ "Allow Chat System Prompt": "Dovoli sistemski poziv v pogovoru", "Allow Chat Valves": "Dovoli pogovor Valves", "Allow Continue Response": "Dovoli nadaljevanje odgovora", + "Allow delegated sub-agents to keep running while the parent chat continues.": "", "Allow Delete Messages": "Dovoli brisanje sporočil", "Allow File Upload": "Dovoli nalaganje datotek", + "Allow forms inside sandboxed artifact iframes.": "", + "Allow Google Drive as a document source.": "", + "Allow models to run generated code and return execution results.": "", + "Allow models to use the code interpreter tool during chats.": "", "Allow Multiple Models in Chat": "Dovoli več modelov v pogovoru", + "Allow new users to create accounts.": "", "Allow non-local voices": "Dovoli non-lokalni voices", + "Allow OneDrive as a document source.": "", "Allow public write access": "Dovoli javni dostop za pisanje", "Allow Rate Response": "Dovoli ocenjevanje odgovora", "Allow Regenerate Response": "Dovoli ponovno ustvarjanje odgovora", + "Allow Sharing With Groups": "", "Allow Sharing With Users": "Dovoli deljenje z uporabniki", "Allow Speech to Text": "Dovoli pretvorbo govora v besedilo", "Allow Temporary Chat": "Dovoli začasni pogovor", "Allow Text to Speech": "Dovoli pretvorbo besedila v govor", + "Allow the AI to delegate tasks to sub-agents. Each sub-agent creates a real chat with full tool access. Uses additional LLM calls.": "", "Allow User Location": "Dovoli lokacijo uporabnika", + "Allow users to access calendar features.": "", + "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", + "Allow users to configure webhooks from their account.": "", + "Allow users to create accounts through OAuth.": "", + "Allow users to create and manage notes.": "", + "Allow users to create and run automations.": "", + "Allow users to create API keys for programmatic access.": "", + "Allow users to edit existing images.": "", + "Allow users to generate images from prompts.": "", + "Allow users to organize chats into folders.": "", + "Allow users to save memories for more personalized responses.": "", + "Allow users to search the web from chats.": "", + "Allow users to share chats with the Open WebUI community.": "", + "Allow users to use channels for shared conversations.": "", "Allow Voice Interruption in Call": "Dovoli Voice Interruption in Call", "Allow Web Upload": "Dovoli Web Upload", "Allowed Domains": "Dovoljene domene", "Allowed Endpoints": "Dovoljene končne točke", "Allowed File Extensions": "Dovoljene končnice datotek", - "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.", "Allowed Roles": "Dovoljene vloge", "Already have an account?": "Že imate račun?", + "Also bound to {{action}}": "", "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": "Vedno", "Always Collapse Code Blocks": "Vedno strni bloke kode", "Always Expand Details": "Vedno razširi podrobnosti", - "Always Play Notification Sound": "Vedno predvajaj zvok obvestila", "Amazing": "Odlično", "an assistant": "an assistant", "Analytics": "Analitika", @@ -194,22 +239,36 @@ "and create a new shared link.": "in ustvarite novo povezavo za deljenje.", "Android": "Android", "Anyone": "Kdor koli", + "Anyone with the link can view": "", + "API Auth String": "", "API Base URL": "Osnovni URL API-ja", - "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker", "API Key": "API ključ", "API Key / Token": "API ključ / žeton", "API Key created.": "API ključ je ustvarjen.", "API Key Endpoint Restrictions": "API Key Endpoint Restrictions", + "API key for embedding requests.": "", + "API key sent to Docling.": "", + "API key sent to Mistral OCR.": "", + "API key sent to the external document loader.": "", + "API key sent to the external reranker.": "", + "API key used for MinerU cloud mode.": "", + "API key used to authenticate with Datalab Marker.": "", "API keys": "API ključi", "API Keys": "API ključi", "API Mode": "Način API-ja", "API Timeout": "Časovna omejitev API-ja", + "API Token": "", + "API token sent to PaddleOCR-vl.": "", "API Type": "Vrsta API-ja", + "API URL": "", "API Version": "Različica API-ja", "API Version is required": "Različica API-ja je obvezna", + "Append a watermark to assistant responses when configured.": "", "Application DN": "DN aplikacije", "Application DN Password": "Geslo DN aplikacije", "applies to all users with the \"user\" role": "applies to all users with the \"user\" role", + "Apply image compression to channel uploads too.": "", + "Apply voice-specific instructions while voice mode is active.": "", "April": "april", "Archive": "Arhiviraj", "Archive All": "Arhiviraj vse", @@ -240,10 +299,13 @@ "Ask a test question": "Ask a test question", "Ask this knowledge source a test question": "Ask this knowledge source a test question", "Assistant": "Asistent", + "Assistant messages": "", "Async Embedding Processing": "Async Embedding Processing", + "at": "", "At time of event": "Ob času dogodka", "Attach File From Knowledge": "Priloži datoteko iz baze znanja", "Attach Files": "Priloži datoteke", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Priloži bazo znanja", "Attach Notes": "Priloži zapiske", "Attach Webpage": "Priloži spletno stran", @@ -267,14 +329,14 @@ "Autocomplete Generation Input Max Length": "Autocomplete Generation Input Max Length", "Autocomplete Generation Prompt": "Autocomplete Generation Prompt", "Automatic": "Samodejno", + "Automatic Delivery": "", + "Automatic Events": "", "Automatic1111": "Automatic1111", - "AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 Api Auth String", - "AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL", "AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 osnovni URL je obvezno.", "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)", "Automation": "Avtomatizacija", "Automation created": "Avtomatizacija je ustvarjena", - "Automation Name": "Ime avtomatizacije", + "Automation Menu": "", "Automation title": "Naslov avtomatizacije", "Automation triggered": "Avtomatizacija je sprožena", "Automation updated": "Avtomatizacija je posodobljena", @@ -283,23 +345,33 @@ "Available models": "Razpoložljivi modeli", "Available Skills": "Razpoložljive veščine", "Available Tools": "Razpoložljiva orodja", - "available users": "razpoložljivi uporabniki", "Available variables": "Razpoložljive spremenljivke", "available!": "available!", + "Average messages per active day": "", + "Average tokens per chat": "", "Away": "Odsoten", "Awful": "Zelo slabo", "Azure AI Speech": "Azure AI Speech", "Azure OpenAI": "Azure OpenAI", + "Azure OpenAI API key.": "", + "Azure OpenAI API version.": "", + "Azure OpenAI endpoint used for embeddings.": "", "Azure Region": "Azure Region", "Back": "Nazaj", + "Background sub-agent finished": "", + "background sub-agents": "", "Bad Response": "Slab odgovor", + "Balance semantic and lexical weighting for hybrid search.": "", "Banners": "Pasice", + "Base DN used when searching for users.": "", "Base Model (From)": "Osnovni model (iz)", "Base Model is required.": "Osnovni model je obvezen.", "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.", + "Base URL": "", "Bearer": "Bearer", "before": "pred", "Being lazy": "Površnost", + "Bind DN used for directory search.": "", "Bing": "Bing", "Bing Search V7 Endpoint": "Bing Search V7 Endpoint", "Bing Search V7 Subscription Key": "Bing Search V7 Subscription Key", @@ -314,6 +386,7 @@ "Brave Search API Key": "Brave Search API Key", "Break down complex requests into trackable steps": "Break down complex requests into trackable steps", "Browse and query knowledge bases": "Brskanje in poizvedovanje po bazah znanja", + "Browser Notifications": "", "Builtin Tools": "Vgrajena orodja", "Bullet List": "Označen seznam", "Button ID": "ID gumba", @@ -321,6 +394,7 @@ "Button Prompt": "Poziv gumba", "by {{name}}": "Avtor: {{name}}", "By {{name}}": "Avtor: {{name}}", + "By supporting the project through sponsorship or an enterprise license, you help us stay independent, ship new features faster, improve stability, and grow Open WebUI for the long haul.": "", "Bypass Embedding and Retrieval": "Preskoči vdelavo in iskanje", "Bypass Web Loader": "Preskoči spletni nalagalnik", "Cache Base Model List": "Cache Base Model List", @@ -332,6 +406,7 @@ "Calendars Public Sharing": "Calendars Public Sharing", "Call": "Klic", "Call feature is not supported when using Web STT engine": "Call feature is not supported when using Web STT engine", + "Callback URI registered with the provider.": "", "Camera": "Kamera", "Cancel": "Prekliči", "Cancel download of {{model}}": "Cancel download of {{model}}", @@ -340,6 +415,7 @@ "Capabilities": "Zmožnosti", "Capture": "Zajemi", "Capture Audio": "Zajemi zvok", + "Certificate file used for TLS verification.": "", "Certificate Path": "Pot do certifikata", "Change folder icon": "Spremeni ikono mape", "Change Password": "Spremeni geslo", @@ -353,9 +429,8 @@ "Channel updated successfully": "Kanal je uspešno posodobljen", "Channels": "Kanali", "Character": "Znak", - "Character limit for autocomplete generation input": "Character limit for autocomplete generation input", - "Chart new frontiers": "Odkrijte nova obzorja", "Chat": "Pogovor", + "Chat actions": "", "Chat archived.": "Pogovor je arhiviran.", "Chat Background Image": "Slika ozadja pogovora", "Chat Bubble UI": "Vmesnik z oblački pogovora", @@ -364,30 +439,68 @@ "Chat deleted.": "Pogovor je izbrisan.", "Chat Direction": "Smer pogovora", "Chat exported successfully": "Pogovor je uspešno izvožen", + "Chat forked": "", + "Chat history": "", "Chat History": "Zgodovina pogovorov", "Chat ID": "ID pogovora", + "Chat is too short to compact": "", "Chat moved successfully": "Pogovor je uspešno premaknjen", "Chat Permissions": "Dovoljenja za pogovor", "Chat Tags Auto-Generation": "Samodejno ustvarjanje oznak pogovora", "Chat unshared successfully.": "Deljenje pogovora je uspešno preklicano.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "pogovori", "Chats": "Pogovori", + "Chats Open Sharing": "", "Chats Public Sharing": "Chats Public Sharing", "Check Again": "Preveri znova", "Check for updates": "Preveri posodobitve", "Checking for updates...": "Preverjanje posodobitev ...", "Choose a model before saving...": "Pred shranjevanjem izberite model ...", + "Choose automatic, left-to-right, or right-to-left text flow.": "", + "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", + "Choose how extracted text is split before indexing.": "", + "Choose how uploaded documents are parsed before indexing.": "", + "Choose how web result pages are fetched and read.": "", + "Choose the browser voice used for speech output.": "", + "Choose the color theme used by the interface.": "", + "Choose the configured text-to-speech service voice.": "", + "Choose the engine used to read assistant responses aloud.": "", + "Choose the engine used to transcribe voice input.": "", + "Choose the gender value stored on your profile.": "", + "Choose the Kokoro.js voice used for speech output.": "", + "Choose the language used for interface text.": "", + "Choose the local or cloud MinerU API mode.": "", + "Choose the provider used for image edits.": "", + "Choose the provider used for image generation.": "", + "Choose the provider used for web search queries.": "", + "Choose the runtime used by the code interpreter tool.": "", + "Choose the runtime used for generated code blocks.": "", + "Choose the speech provider used for assistant audio output.": "", + "Choose the transcription provider used for audio input.": "", + "Choose whether Enter sends immediately or uses Ctrl+Enter.": "", + "Choose whether the app opens to the default home or chat view.": "", "Chunk Min Size Target": "Chunk Min Size Target", "Chunk Overlap": "Prekrivanje kosov", "Chunk Size": "Velikost kosa", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.", "Ciphers": "Ciphers", "Citation": "Navedba vira", "Citations": "Navedbe virov", + "Claim containing provider groups.": "", + "Claim containing provider roles.": "", + "Claim used as the display name.": "", + "Claim used as the profile picture URL.": "", + "Claim used as the stable user identifier.": "", + "Claim used as the user email address.": "", + "Clear": "", + "Clear filters to reorder": "", "Clear memory": "Počisti pomnilnik", "Clear Memory": "Počisti pomnilnik", "Clear search": "Počisti iskanje", "Clear status": "Počisti stanje", + "Clear vector storage and knowledge indexing data.": "", "click here": "kliknite tukaj", "Click here for filter guides.": "Kliknite tukaj za vodnike po filtrih.", "Click here for help.": "Kliknite tukaj za pomoč.", @@ -397,12 +510,12 @@ "Click here to see available models.": "Kliknite tukaj za see available models.", "Click here to select": "Kliknite tukaj za izbiro", "Click here to select a csv file.": "Kliknite tukaj za select a csv file.", - "Click here to select a py file.": "Kliknite tukaj za select a py file.", "Click here to upload a workflow.json file.": "Kliknite tukaj za 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.", "Click to connect": "Kliknite za povezavo", "Click to copy ID": "Kliknite za kopiranje ID-ja", + "Click to rebind": "", "Client ID": "ID odjemalca", "Client Secret": "Skrivnost odjemalca", "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Clipboard write permission denied. Please check your browser settings to grant the necessary access.", @@ -417,7 +530,6 @@ "Close feedback": "Zapri povratne informacije", "Close modal": "Zapri okno", "Close Modal": "Zapri okno", - "Close settings modal": "Zapri okno z nastavitvami", "Close Sidebar": "Zapri stransko vrstico", "cloud": "oblak", "CMU ARCTIC speaker embedding name": "CMU ARCTIC speaker embedding name", @@ -433,44 +545,61 @@ "Code Interpreter Prompt Template": "Code Interpreter Prompt Template", "Collaboration channel where people join as members": "Collaboration channel where people join as members", "Collapse": "Collapse", + "Collapse code blocks by default.": "", "Collection": "Zbirka", "Collection Field": "Collection Field", "Collections": "Zbirke", "Color": "Barva", + "Combine semantic and keyword retrieval.": "", "ComfyUI": "ComfyUI", - "ComfyUI API Key": "ComfyUI API Key", - "ComfyUI Base URL": "ComfyUI Base URL", "ComfyUI Base URL is required.": "ComfyUI osnovni URL je obvezno.", "ComfyUI Workflow": "ComfyUI Workflow", "ComfyUI Workflow Nodes": "ComfyUI Workflow Nodes", "Comma separated Node Ids (e.g. 1 or 1,2)": "Comma separated Node Ids (e.g. 1 or 1,2)", + "Comma-separated API paths that API keys can access.": "", + "Comma-separated audio or video MIME types accepted for upload.": "", + "Comma-separated extensions MinerU should handle.": "", "Comma-separated group names": "Comma-separated group names", - "Comma-separated list of file extensions MinerU will handle (e.g. pdf, docx, pptx, xlsx)": "Comma-separated list of file extensions MinerU will handle (e.g. pdf, docx, pptx, xlsx)", + "Comma-separated top-level request parameters this upstream may receive without translation. Use * to allow all captured passthrough params.": "", + "Comma-separated upload extensions. Leave empty for all file types.": "", "command": "command", "Command": "Ukaz", + "Commands": "", "Comment": "Komentar", "Commit Message": "Sporočilo commita", + "Community": "", "Community Reviews": "Ocene skupnosti", + "Community Sharing": "", "Compacting context": "Compacting context", + "Compacting context...": "", + "Compare": "", "Comparing with knowledge base...": "Comparing with knowledge base...", "Completions": "Dopolnitve", "Compress Images in Channels": "Compress Images in Channels", + "Compress uploaded images before sending or storage.": "", "Computing checksums ({{count}} files)_one": "Computing checksums ({{count}} files)_one", + "Computing checksums ({{count}} files)_two": "", + "Computing checksums ({{count}} files)_few": "", "Computing checksums ({{count}} files)_other": "Computing checksums ({{count}} files)_other", "Concurrent Requests": "Sočasne zahteve", "Config": "Konfiguracija", "Config imported successfully": "Konfiguracija je uspešno uvožena", - "Configuration": "Konfiguracija", "Configure": "Konfiguriraj", "Confirm": "Potrdi", "Confirm Password": "Potrdi geslo", "Confirm Prompt from Embed": "Confirm Prompt from Embed", + "Confirm recording": "", "Confirm your action": "Potrdite dejanje", "Confirm your new password": "Potrdite novo geslo", "Confirm Your Password": "Potrdite geslo", + "Connect code execution to a Jupyter server endpoint.": "", + "Connect code interpreter to a Jupyter server endpoint.": "", + "Connect to a stable-diffusion-webui server running with the `--api` flag.": "", "Connect to an AI provider to start chatting": "Poveži to an AI provider to start chatting", "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "Poveži to Open terminal instances to browse files and use them as always-on tools. Only one can be active at a time.", "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "Poveži to Open terminal instances. All users will have access to file browsing and terminal tools through these servers.", + "Connect to the ComfyUI server used for generation.": "", + "Connect to the ComfyUI server used for image edits.": "", "Connect to your own OpenAI compatible API endpoints.": "Poveži to your own OpenAI compatible API endpoints.", "Connect to your own OpenAPI compatible external tool servers.": "Poveži to your own OpenAPI compatible zunanji tool servers.", "Connected": "Povezano", @@ -485,6 +614,7 @@ "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": "Vsebina", + "Content Extraction": "", "Content Extraction Engine": "Content Extraction Engine", "Content Field": "Polje vsebine", "Content lengths (character counts only)": "Content lengths (character counts only)", @@ -492,6 +622,7 @@ "Context compacted": "Kontekst je strnjen", "Context Compaction": "Strnjevanje konteksta", "Context compaction failed": "Strnjevanje konteksta ni uspelo", + "Context compaction is disabled": "", "Context Compaction Prompt": "Context Compaction Prompt", "Context Compaction Threshold": "Context Compaction Threshold", "Context Tokens": "Žetoni konteksta", @@ -501,10 +632,14 @@ "Continue with Email": "Nadaljuj z e-pošto", "Continue with LDAP": "Continue with 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 result volume and parallel search requests.": "", "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": "Kontrole", + "Controls how chat tags are inferred.": "", + "Controls how older messages are rewritten into a running summary.": "", "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.", "Conversation saved successfully": "Pogovor je uspešno shranjen", + "Convert long pasted text into a file attachment.": "", "Copied": "Kopirano", "Copied link to clipboard": "Povezava je kopirana v odložišče", "Copied shared chat URL to clipboard!": "URL deljenega pogovora je kopiran v odložišče!", @@ -519,12 +654,16 @@ "Copy Link": "Kopiraj povezavo", "Copy Path": "Kopiraj pot", "Copy Prompt": "Kopiraj poziv", + "Copy rich formatted content instead of plain text.": "", "Copy Share Link": "Kopiraj povezavo za deljenje", + "Copy the current session token for authenticated requests.": "", + "Copy the latest assistant response when it completes.": "", "Copy to clipboard": "Kopiraj v odložišče", "Copy Token": "Kopiraj žeton", "Copy URL": "Kopiraj URL", "Copying to clipboard was successful!": "Copying to clipboard was successful!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "CORS must be properly configured by the provider to allow requests from Open WebUI.", + "Could not load release notes.": "", "Could not read file.": "Could not read file.", "CPU": "CPU", "Create": "Ustvari", @@ -534,41 +673,54 @@ "Create Account": "Ustvari račun", "Create Admin Account": "Ustvari skrbniški račun", "Create and manage scheduled automations": "Ustvari and manage scheduled automations", + "Create announcements shown to users in the app.": "", "Create Channel": "Ustvari kanal", + "Create chat tags from conversation content.": "", "Create Folder": "Ustvari mapo", "Create Image": "Ustvari sliko", "Create Knowledge": "Ustvari bazo znanja", + "Create missing groups from LDAP groups.": "", + "Create missing groups from OAuth claims.": "", "Create Model": "Ustvari model", "Create new key": "Ustvari nov ključ", "Create new secret key": "Ustvari nov skrivni ključ", - "Create note": "Ustvari zapisek", - "Create Note": "Ustvari zapisek", - "Create one read-only Knowledge source per external collection. Test must pass before the source is created.": "Ustvari one read-only baza znanja source per zunanji collection. Test must pass before the source is created.", + "Create Prompt": "", "Create scheduled prompts that run automatically on a recurring basis.": "Ustvari scheduled prompts that run automatically on a recurring basis.", - "Create your first note by clicking on the plus button below.": "Ustvari your first note by clicking on the plus button below.", + "Create your first note from the Create menu.": "", + "Create, copy, or rotate your API key.": "", + "Created": "", "Created at": "Ustvarjeno", "Created At": "Ustvarjeno", "Created by": "Ustvaril", "Created by you": "Ustvarili ste vi", "Created on {{date}}": "Ustvarjeno {{date}}", + "Credential used for Document Intelligence.": "", + "Credentials used to authenticate with the Jupyter server.": "", "CSV Import": "Uvoz CSV", "Ctrl+Enter to Send": "Ctrl+Enter za pošiljanje", + "Current": "", "Current Model": "Trenutni model", "Current Password": "Trenutno geslo", + "Current streak": "", "Custom": "Po meri", "Custom color": "Barva po meri", "Custom description enabled": "Opis po meri je omogočen", "Custom Gender": "Spol po meri", + "Custom message shown while an account waits for approval.": "", "Custom Parameter Name": "Ime parametra po meri", "Custom Parameter Value": "Vrednost parametra po meri", + "Custom permissions": "", "Custom range": "Obseg po meri", + "Custom title shown while an account waits for approval.": "", "Daily": "Dnevno", + "Daily at": "", "Daily Messages": "Dnevna sporočila", "Danger Zone": "Nevarno območje", "Dark": "Temno", "Data Controls": "Upravljanje podatkov", "Database": "Podatkovna baza", "Datalab Marker API": "Datalab Marker API", + "Datalab Marker service endpoint used for document parsing.": "", "Date Modified": "Datum spremembe", "Day": "Dan", "DD/MM/YYYY": "DD/MM/YYYY", @@ -591,10 +743,13 @@ "Default Prompt Suggestions": "Privzeti predlogi pozivov", "Default to 389 or 636 if TLS is enabled": "Default to 389 or 636 if TLS is enabled", "Default to ALL": "Default to ALL", + "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.", + "Default Upload Mode": "", "Default User Role": "Privzeta vloga uporabnika", "Default webhook": "Default webhook", - "Defaults": "Privzete vrednosti", + "Defines the behavior used for spoken conversations.": "", + "Delegate focused work to parallel sub-agents": "", "Delete": "Izbriši", "Delete {{name}}": "Izbriši {{name}}", "Delete a model": "Izbriši a model", @@ -621,6 +776,7 @@ "Delete skill?": "Izbrisati veščino?", "delete this link": "izbriši to povezavo", "Delete tool?": "Izbrisati orodje?", + "Delete uploaded files from the upload directory.": "", "Delete User": "Izbriši uporabnika", "Delete Version": "Izbriši različico", "Deleted": "Izbrisano", @@ -637,6 +793,8 @@ "Description": "Opis", "Deselect": "Prekliči izbiro", "Detect Artifacts Automatically": "Samodejno zaznaj artefakte", + "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Narekuj", "Didn't fully follow instructions": "Ni v celoti sledil navodilom", "Direct": "Neposredno", @@ -650,10 +808,10 @@ "Directory name": "Ime mape", "Directory renamed.": "Mapa je preimenovana.", "Directory selection was cancelled": "Directory selection was cancelled", + "Disable all": "", "Disable All": "Onemogoči vse", "Disable Code Interpreter": "Onemogoči tolmač kode", "Disable Image Extraction": "Onemogoči izločanje slik", - "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "Onemogoči image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.", "Disable Image Generation": "Onemogoči ustvarjanje slik", "Disable Web Search": "Onemogoči spletno iskanje", "Disabled": "Onemogočeno", @@ -663,7 +821,6 @@ "Discover a prompt": "Odkrij poziv", "Discover a tool": "Odkrij orodje", "Discover how to use Open WebUI and seek support from the community.": "Discover how to use Open WebUI and seek support from the community.", - "Discover wonders": "Discover wonders", "Discover, download, and explore custom functions": "Discover, download, and explore custom functions", "Discover, download, and explore custom prompts": "Discover, download, and explore custom prompts", "Discover, download, and explore custom tools": "Discover, download, and explore custom tools", @@ -673,38 +830,48 @@ "Display Chat Title in Tab": "Prikaži naslov pogovora v zavihku", "Display Emoji in Call": "Prikaži emoji v klicu", "Display Multi-model Responses in Tabs": "Prikaži odgovore več modelov v zavihkih", + "Display name for this LDAP connection.": "", + "Display name shown for the OAuth provider.": "", "Display the Username Instead of You in the Chat": "V pogovoru prikaži uporabniško ime namesto »Vi«", "Displays citations in the response": "Prikaže navedbe virov v odgovoru", "Displays status updates (e.g., web search progress) in the response": "Displays status updates (e.g., web search progress) in the response", - "Dive into knowledge": "Dive into knowledge", + "Do not extract images from PDFs during Marker processing.": "", "Do not install functions from sources you do not fully trust.": "Do not install functions from sources you do not fully trust.", "Do not install tools from sources you do not fully trust.": "Do not install tools from sources you do not fully trust.", "Do you want to sync your usage stats with Open WebUI Community?": "Do you want to sync your usage stats with Open WebUI Community?", "Docling": "Docling", "Docling Parameters": "Docling Parameters", + "Docling Server URL": "", "Docling Server URL required.": "Docling Server URL required.", + "Docling service endpoint used for parsing.": "", "Document": "Dokument", "Document ID Field": "Document ID Field", "Document Intelligence": "Document Intelligence", "Document Intelligence endpoint required.": "Document Intelligence endpoint required.", + "Document Intelligence endpoint used for parsing.": "", "Document Intelligence Model": "Document Intelligence Model", + "Document Loader URL": "", "Documentation": "Dokumentacija", "Documents": "Dokumenti", "does not make any external connections, and your data stays securely on your locally hosted server.": "does not make any external connections, and your data stays securely on your locally hosted server.", "Domain Filter List": "Seznam filtra domen", - "don't fetch random pipelines from sources you don't trust.": "don't fetch random pipelines from sources you don't trust.", + "Don't fetch random pipelines from sources you don't trust.": "", "Don't have an account?": "Nimate računa?", - "don't install random functions from sources you don't trust.": "don't install random functions from sources you don't trust.", - "don't install random tools from sources you don't trust.": "don't install random tools from sources you don't trust.", "Don't like the style": "Don't like the style", "Done": "Končano", "Download": "Prenesi", "Download & Delete": "Prenesi in izbriši", + "Download all users as CSV.": "", "Download as JSON": "Prenesi kot JSON", "Download as SVG": "Prenesi kot SVG", "Download canceled": "Prenos je preklican", - "Download Database": "Prenesi podatkovno bazo", + "Download every user's chat history as JSON.": "", + "Download failed": "", + "Download the application database when supported.": "", + "Download the current admin configuration as JSON.": "", + "Download your chat history as a JSON export.": "", "Downloading stats...": "Prenašanje statistike ...", + "Drag to reorder": "", "Draw": "Nariši", "Drop any files here to upload": "Spustite datoteke sem za nalaganje", "Drop files here": "Spustite datoteke sem", @@ -747,17 +914,17 @@ "Edit Terminal Connection": "Uredi terminalsko povezavo", "Edit User": "Uredi uporabnika", "Edit User Group": "Uredi skupino uporabnikov", + "Edit User Variable": "", "Edit webhook": "Uredi webhook", "Edit workflow.json content": "Uredi workflow.json content", "edited": "urejeno", - "Edited": "Urejeno", - "Editing": "Urejanje", "Eject": "Izvrzi", "Eject model": "Izvrzi model", "ElevenLabs": "ElevenLabs", "Email": "E-pošta", "Email Claim": "Email Claim", - "Embark on adventures": "Embark on adventures", + "Email domains allowed to sign in with OAuth.": "", + "Email shown in the pending account overlay.": "", "Embedding": "Vdelava", "Embedding Batch Size": "Velikost paketa vdelav", "Embedding Concurrent Requests": "Sočasne zahteve za vdelave", @@ -768,29 +935,26 @@ "Empty": "Prazno", "Empty message": "Prazno sporočilo", "Enable All": "Omogoči vse", - "Enable API Keys": "Omogoči API ključe", - "Enable autocomplete generation for chat messages": "Omogoči samodejno dopolnjevanje sporočil v pogovoru", + "Enable background sub-agents": "", "Enable Code Execution": "Omogoči izvajanje kode", "Enable Code Interpreter": "Omogoči tolmač kode", - "Enable Community Sharing": "Omogoči deljenje s skupnostjo", - "Enable Group Mapping": "Omogoči preslikavo skupin", "Enable Image Generation": "Omogoči ustvarjanje slik", + "Enable Keyboard Shortcuts": "", "Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Omogoči pomnilnik Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.", "Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Omogoči pomnilnik Mapping (mmap) to load model data. This option allows the sistemski to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.", "Enable Message Queue": "Omogoči čakalno vrsto sporočil", - "Enable Message Rating": "Omogoči ocenjevanje sporočil", "Enable Mirostat sampling for controlling perplexity.": "Omogoči Mirostat sampling for controlling perplexity.", - "Enable New Sign Ups": "Omogoči nove registracije", - "Enable OAuth Signup": "Omogoči registracijo z OAuth", - "Enable Role Mapping": "Omogoči preslikavo vlog", + "Enable sub-agents": "", "Enable Web Search": "Omogoči spletno iskanje", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.", "Enabled": "Omogočeno", + "End call": "", "End Tag": "Končna oznaka", "Endpoint": "Končna točka", "Endpoint URL": "URL končne točke", "Enforce Temporary Chat": "Vsili začasni pogovor", "Enhance": "Izboljšaj", + "Enhance this note and update it.": "", "Enrich Hybrid Search Text": "Enrich Hybrid Search Text", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Preverite, da datoteka CSV vsebuje 4 stolpce v tem vrstnem redu: Ime, E-pošta, Geslo, Vloga.", "Enter {{role}} message here": "Tukaj vnesite sporočilo za vlogo {{role}}", @@ -798,6 +962,7 @@ "Enter a watermark for the response. Leave empty for none.": "Vnesite a watermark for the response. leave empty for none.", "Enter additional headers in JSON format": "Vnesite dodatni headers in json format", "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "Vnesite dodatni headers in json format (e.g. {\"x-po meri-header\": \"value\"}", + "Enter additional OpenAI-compatible TTS request parameters as JSON.": "", "Enter additional parameters in JSON format": "Vnesite dodatni parameters in json format", "Enter api auth string (e.g. username:password)": "Vnesite api auth string (e.g. username:password)", "Enter Application DN": "Vnesite application dn", @@ -836,7 +1001,7 @@ "Enter Firecrawl Timeout": "Vnesite firecrawl timeout", "Enter folder name": "Vnesite folder name", "Enter function name filter list (e.g. func1, !func2)": "Vnesite function name filter list (e.g. func1, !func2)", - "Enter Github Raw URL": "Vnesite github raw url", + "Enter GitHub Raw URL": "", "Enter Google PSE API Key": "Vnesite google pse api ključ", "Enter Google PSE Engine Id": "Vnesite google pse engine id", "Enter hex color (e.g. #FF0000)": "Vnesite hex color (e.g. #ff0000)", @@ -857,7 +1022,6 @@ "Enter MinerU API Key": "Vnesite mineru api ključ", "Enter Mistral API Base URL": "Vnesite mistral api osnovni url", "Enter Mistral API Key": "Vnesite mistral api ključ", - "Enter Model ID": "Vnesite model id", "Enter model tag (e.g. {{modelTag}})": "Vnesite oznako modela (npr. {{modelTag}})", "Enter Mojeek Search API Key": "Vnesite mojeek iskanje api ključ", "Enter name": "Vnesite ime", @@ -897,12 +1061,10 @@ "Enter system prompt here": "Tukaj vnesite sistemski poziv", "Enter Tavily API Key": "Vnesite tavily api ključ", "Enter Tavily Extract Depth": "Vnesite tavily extract depth", - "Enter the prompt instructions for this automation...": "Vnesite the prompt instructions for this automation.", "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Vnesite the javno url of your webui. this url will be used to generate links in the notifications.", "Enter the URL of the function to import": "Vnesite the url of the function to import", "Enter the URL to import": "Vnesite the url to import", "Enter Tika Server URL": "Vnesite tika server url", - "Enter timeout in seconds": "Vnesite timeout in seconds", "Enter to Send": "Enter za pošiljanje", "Enter token threshold": "Vnesite token threshold", "Enter Tokenizer Model": "Vnesite tokenizer model", @@ -930,7 +1092,8 @@ "Enter Your Password": "Vnesite geslo", "Enter Your Role": "Vnesite vlogo", "Enter Your Username": "Vnesite uporabniško ime", - "Enter your webhook URL": "Vnesite your webhook url", + "Enterprise licenses also include dedicated support, customization options, and more, at a fraction of the cost of building and maintaining this stack internally.": "", + "Enterprise licensing": "", "Entra ID": "Entra ID", "Environment Variables": "Okoljske spremenljivke", "Ephemeral": "Ephemeral", @@ -953,6 +1116,15 @@ "Event title": "Naslov dogodka", "Event updated": "Dogodek je posodobljen", "Events": "Dogodki", + "Every {{count}} hours_one": "", + "Every {{count}} hours_two": "", + "Every {{count}} hours_few": "", + "Every {{count}} hours_other": "", + "Every {{count}} minutes_one": "", + "Every {{count}} minutes_two": "", + "Every {{count}} minutes_few": "", + "Every {{count}} minutes_other": "", + "Every minute": "", "Exa API Key": "Exa API Key", "Example": "Primer", "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Example: (&(objectClass=inetOrgPerson)(uid=%s))", @@ -964,33 +1136,31 @@ "Exclude": "Izključi", "Execute code": "Izvedi kodo", "Execute code for analysis": "Izvedi kodo za analizo", - "Executing **{{NAME}}**...": "Executing **{{NAME}}**...", - "Execution Logs": "Dnevniki izvajanja", + "Executing {{NAME}}...": "", "Expand": "Razširi", "Experimental": "Eksperimentalno", "Explain": "Pojasni", - "Explore the cosmos": "Explore the cosmos", "Explored": "Explored", "Exploring": "Exploring", "Export": "Izvozi", - "Export All Archived Chats": "Izvozi vse arhivirane pogovore", - "Export All Chats (All Users)": "Izvozi vse pogovore (vsi uporabniki)", "Export as CSV": "Izvozi kot CSV", "Export as JSON": "Izvozi kot JSON", "Export chat (.json)": "Izvozi pogovor (.json)", "Export Chats": "Izvozi pogovore", "Export Config": "Izvozi konfiguracijo", + "Export JSON": "", "Export Models": "Izvozi modele", "Export Prompts": "Izvozi pozive", "Export Skills": "Izvozi veščine", "Export to CSV": "Izvozi v CSV", "Export Tools": "Izvozi orodja", - "Export Users": "Izvozi uporabnike", "External": "Zunanje", "External connection not found.": "External connection not found.", "External Document Loader URL required.": "External Document Loader URL required.", "External Knowledge Source": "Zunanji vir znanja", "External Knowledge Sources": "Zunanji viri znanja", + "External reranker endpoint.": "", + "External service endpoint used to load document content.": "", "External Task Model": "Zunanji model za naloge", "External Tool Servers": "External Tool Servers", "External vectors must be generated with the same embedding model configured in Open WebUI.": "External vectors must be generated with the same embedding model configured in Open WebUI.", @@ -998,7 +1168,10 @@ "External Web Loader URL": "External Web Loader URL", "External Web Search API Key": "External Web Search API Key", "External Web Search URL": "External Web Search URL", + "Extract action items from this note.": "", + "Extract images from PDFs so OCR can process image-only pages.": "", "Fade Effect for Streaming Text": "Učinek pojemanja pri pretočnem besedilu", + "Fade streaming text as it arrives.": "", "Failed to add file.": "Dodajanje datoteke ni uspelo.", "Failed to add members": "Ni uspelo: add members", "Failed to archive chat.": "Arhiviranje pogovora ni uspelo.", @@ -1009,6 +1182,7 @@ "Failed to connect to {{URL}} terminal server": "Povezava s terminalskim strežnikom na {{URL}} ni uspela", "Failed to copy link": "Kopiranje povezave ni uspelo", "Failed to create API Key.": "Ustvarjanje API ključa ni uspelo.", + "Failed to create chat": "", "Failed to delete calendar": "Ni uspelo: delete calendar", "Failed to delete note": "Brisanje zapiska ni uspelo", "Failed to delete webhook": "Ni uspelo: delete webhook", @@ -1017,6 +1191,7 @@ "Failed to extract content from the file: {{error}}": "Ni uspelo: extract content from the file: {{error}}", "Failed to extract content from the file.": "Ni uspelo: extract content from the file.", "Failed to fetch models": "Pridobivanje modelov ni uspelo", + "Failed to fork chat": "", "Failed to generate title": "Ustvarjanje naslova ni uspelo", "Failed to import models": "Uvoz modelov ni uspel", "Failed to load chat": "Nalaganje pogovora ni uspelo", @@ -1025,7 +1200,9 @@ "Failed to load Excel/CSV file. Please try downloading it instead.": "Ni uspelo: load excel/csv file. please try downloading it instead.", "Failed to load file content.": "Nalaganje vsebine datoteke ni uspelo.", "Failed to load Interface settings": "Ni uspelo: load interface settings", + "Failed to load policy: {{error}}": "", "Failed to load PPTX file. Please try downloading it instead.": "Ni uspelo: load pptx file. please try downloading it instead.", + "Failed to load usage": "", "Failed to move chat": "Premik pogovora ni uspel", "Failed to process URL: {{url}}": "Ni uspelo: process url: {{url}}", "Failed to read clipboard contents": "Ni uspelo: read clipboard contents", @@ -1033,6 +1210,7 @@ "Failed to remove member": "Ni uspelo: remove member", "Failed to render diagram": "Prikaz diagrama ni uspel", "Failed to render visualization": "Ni uspelo: render visualization", + "Failed to save chat variables": "", "Failed to save connections": "Ni uspelo: save connections", "Failed to save conversation": "Shranjevanje pogovora ni uspelo", "Failed to save models configuration": "Ni uspelo: save models configuration", @@ -1051,9 +1229,9 @@ "Feedback Activity": "Dejavnost povratnih informacij", "Feedback deleted successfully": "Povratna informacija je uspešno izbrisana", "Feedback Details": "Podrobnosti povratnih informacij", - "Feedback History": "Zgodovina povratnih informacij", "Feel free to add specific details": "Feel free to add specific details", "Female": "Ženski", + "Fetch page contents without proxy environment variables.": "", "Fetch URL Content Length Limit": "Fetch URL Content Length Limit", "File": "Datoteka", "File added successfully.": "Datoteka je uspešno dodana.", @@ -1100,6 +1278,7 @@ "Folder updated successfully": "Mapa je uspešno posodobljena", "Folders": "Mape", "Folders Sharing": "Folders Sharing", + "Follow assistant responses as they are generated.": "", "Follow up": "Nadaljnje vprašanje", "Follow Up Generation": "Ustvarjanje nadaljnjih vprašanj", "Follow Up Generation Prompt": "Follow Up Generation Prompt", @@ -1108,18 +1287,19 @@ "Followed instructions perfectly": "Popolnoma je sledil navodilom", "for placeholders": "for placeholders", "Force OCR": "Vsili 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.", - "Forge new paths": "Forge new paths", + "Forking chat...": "", "Form": "Obrazec", "Format Lines": "Oblikuj vrstice", - "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.": "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.", + "Format lines to detect inline math and styles.": "", + "Format Markdown in previews and compact content surfaces.": "", + "Format Markdown syntax in assistant responses.": "", + "Format Markdown syntax in your own messages.": "", "Formatting may be inconsistent from source.": "Oblikovanje je lahko nedosledno glede na vir.", "Forward": "Posreduj", "Forwards system user OAuth access token to authenticate": "Forwards system user OAuth access token to authenticate", "Forwards system user session credentials to authenticate": "Forwards system user session credentials to authenticate", "Fr_day_of_week": "Fr_day_of_week", "Full Context Mode": "Način polnega konteksta", - "Function": "Funkcija", "Function Calling": "Klicanje funkcij", "Function created successfully": "Funkcija je uspešno ustvarjena", "Function deleted successfully": "Funkcija je uspešno izbrisana", @@ -1128,32 +1308,39 @@ "Function imported successfully": "Funkcija je uspešno uvožena", "Function is now globally disabled": "Funkcija je zdaj globalno onemogočena", "Function is now globally enabled": "Funkcija je zdaj globalno omogočena", + "Function Menu": "", "Function Name": "Ime funkcije", "Function Name Filter List": "Function Name Filter List", "Function starter": "Začetek funkcije", "Function updated successfully": "Funkcija je uspešno posodobljena", "Functions": "Funkcije", "Functions allow arbitrary code execution.": "Funkcije omogočajo izvajanje poljubne kode.", + "Functions can execute arbitrary code.": "", "Functions imported successfully": "Funkcije so uspešno uvožene", "Gemini": "Gemini", - "Gemini API Key": "Gemini API Key", "Gemini API Key is required.": "Gemini API ključ je obvezno.", - "Gemini Base URL": "Gemini Base URL", "Gemini Endpoint Method": "Gemini Endpoint Method", "Gender": "Spol", "General": "Splošno", "Generate": "Ustvari", "Generate an image": "Ustvari sliko", + "Generate an image prompt before sending the request.": "", "Generate and edit images": "Ustvari in urejaj slike", + "Generate message pair": "", + "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Ustvari sporočilo Pair", + "Generate suggested follow-up prompts after responses.": "", + "Generate tags for chats automatically.": "", "Generated Image": "Ustvarjena slika", "Generated images will appear here": "Ustvarjene slike se bodo prikazale tukaj", "Generating search query": "Ustvarjanje iskalne poizvedbe", "Generating...": "Ustvarjanje ...", + "Generation": "", "Get current time and perform date/time calculations": "Get current time and perform date/time calculations", "Get information on {{name}} in the UI": "Get information on {{name}} in the UI", "Get started": "Začni", "Get started with {{WEBUI_NAME}}": "Get started with {{WEBUI_NAME}}", + "GitHub URL": "", "Global": "Globalno", "Good Response": "Dober odgovor", "Google": "Google", @@ -1165,15 +1352,22 @@ "Grokipedia": "Grokipedia", "group": "skupina", "Group": "Skupina", + "Group assigned to new users by default.": "", + "Group Attribute": "", "Group Channel": "Skupinski kanal", "Group Claim": "Zahtevek skupine", "Group created successfully": "Skupina je uspešno ustvarjena", "Group deleted successfully": "Skupina je uspešno izbrisana", "Group Description": "Opis skupine", + "Group Mapping": "", + "Group multi-model responses into tabs.": "", "Group Name": "Ime skupine", "Group updated successfully": "Skupina je uspešno posodobljena", "groups": "skupine", "Groups": "Skupine", + "Guides how the assistant formats tool and function calls.": "", + "Guides inline completions while users type a message.": "", + "Guides the suggestions shown after an assistant response.": "", "H1": "H1", "H2": "H2", "H3": "H3", @@ -1182,6 +1376,7 @@ "Headers": "Glave", "Headers must be a valid JSON object": "Headers must be a valid JSON object", "Height": "Višina", + "Height in pixels to compress images to. Leave empty for no compression.": "", "Hello, {{name}}": "Pozdravljeni, {{name}}", "Help": "Pomoč", "Help the community discover great models": "Help the community discover great models", @@ -1214,7 +1409,6 @@ "Idle Timeout": "Časovna omejitev mirovanja", "iframe Sandbox Allow Forms": "iframe Sandbox Allow Forms", "iframe Sandbox Allow Same Origin": "iframe Sandbox Allow Same Origin", - "Ignite curiosity": "Ignite curiosity", "Image": "Slika", "Image Compression": "Stiskanje slik", "Image Compression Height": "Višina stiskanja slike", @@ -1231,43 +1425,54 @@ "Image Size": "Velikost slike", "Images": "Slike", "Import": "Uvozi", + "Import admin configuration from a JSON export file.": "", + "Import chat history from a JSON export file.": "", "Import Chats": "Uvozi pogovore", "Import Config": "Uvozi konfiguracijo", "Import From Link": "Uvozi iz povezave", + "Import JSON": "", "Import Models": "Uvozi modele", "Import Prompts": "Uvozi pozive", "Import Skills": "Uvozi veščine", "Import successful": "Uvoz je uspel", "Import Tools": "Uvozi orodja", + "Import txt/md": "", "Important Update": "Pomembna posodobitev", + "Imported automations successfully": "", + "Imported notes successfully": "", "Inactive": "Neaktivno", "Include": "Vključi", - "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": "Include `--api` flag when running stable-diffusion-webui", - "Includes SharePoint": "Includes SharePoint", + "Include saved memories in the system context.": "", + "Include voices that are not provided by a local speech service.": "", + "Increase contrast for controls and input surfaces.": "", "Increase UI Scale": "Povečaj merilo vmesnika", "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.", "Info": "Informacije", "Initials": "Začetnice", + "Inject entire documents as context for comprehensive processing.": "", "Inject file content into conversation context": "Inject file content into conversation context", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.", + "Inject the entire content as context for comprehensive processing.": "", "Input": "Vnos", "Input Key (e.g. text, unet_name, steps)": "Input Key (e.g. text, unet_name, steps)", "Input Variables": "Vhodne spremenljivke", "Insert": "Vstavi", "Insert Follow-Up Prompt to Input": "Insert Follow-Up Prompt to Input", + "Insert into note": "", "Insert Prompt as Rich Text": "Insert Prompt as Rich Text", + "Insert selected follow-up prompts directly into the composer.": "", "Insert Suggestion Prompt to Input": "Insert Suggestion Prompt to Input", - "Install from Github URL": "Install from Github URL", + "Install": "", + "Installing": "", "Instant Auto-Send After Voice Transcription": "Instant Auto-Send After Voice Transcription", "Instructions": "Navodila", "Integration": "Integracija", "Integrations": "Integracije", "Interface": "Vmesnik", "Interface Settings Access": "Dostop do nastavitev vmesnika", - "Invalid file content": "Neveljavna vsebina datoteke", "Invalid file format.": "Neveljavna oblika datoteke.", "Invalid JSON file": "Neveljavna datoteka JSON", + "Invalid JSON format": "", "Invalid JSON format for ComfyUI Edit Workflow.": "Invalid JSON format for ComfyUI Edit Workflow.", "Invalid JSON format for ComfyUI Workflow.": "Invalid JSON format for ComfyUI Workflow.", "Invalid JSON format for Parameters": "Neveljavna oblika JSON za parametre", @@ -1282,20 +1487,26 @@ "join our Discord for help.": "join our Discord for help.", "JSON": "JSON", "JSON Base64": "JSON Base64", + "JSON options passed to Marker for advanced parsing behavior.": "", "JSON Preview": "Predogled JSON", "JSON Spec": "JSON Spec", "July": "julij", "June": "junij", "Jupyter Auth": "Jupyter Auth", + "Jupyter Password": "", + "Jupyter Token": "", "Jupyter URL": "Jupyter URL", "JWT Expiration": "Potek JWT", "JWT Token": "Žeton JWT", "Kagi Search API Key": "Kagi Search API Key", + "Keep current webhook URL": "", "Keep Follow-Up Prompts in Chat": "Keep Follow-Up Prompts in Chat", + "Keep generated follow-up prompts visible in the chat.": "", "Keep in Sidebar": "Obdrži v stranski vrstici", "Key": "Ključ", "Key is required": "Ključ je obvezen", - "Keyboard Shortcuts": "Bližnjice na tipkovnici", + "key_name": "", + "Keyboard": "", "Knowledge": "Baza znanja", "Knowledge Access": "Dostop do baze znanja", "Knowledge Base": "Baza znanja", @@ -1322,17 +1533,23 @@ "Last 90 days": "Zadnjih 90 dni", "Last Active": "Zadnja aktivnost", "Last Modified": "Nazadnje spremenjeno", - "Last ran": "Zadnji zagon", "Last reply": "Zadnji odgovor", + "Last run": "", "LDAP": "LDAP", + "LDAP attribute containing the user group memberships.": "", + "LDAP attribute used as the user email address.": "", + "LDAP attribute used as the username.": "", + "LDAP filter used to match signing-in users.": "", + "LDAP server hostname or IP address.": "", + "LDAP server port.": "", "Leaderboard": "Leaderboard", - "Learn more": "Več o tem", "Learn More": "Več o tem", "Learn more about Open Terminal": "Learn more about Open Terminal", "Learn more about OpenAPI tool servers.": "Learn more about OpenAPI tool servers.", "Learn more about Voxtral transcription.": "Learn more about Voxtral transcription.", "Leave a public review for {{modelName}}": "Leave a public review for {{modelName}}", "Leave empty for no compression": "Pustite prazno za brez stiskanja", + "Leave empty for the built-in default.": "", "Leave empty for unlimited": "Pustite prazno za neomejeno", "Leave empty to include all models from \"{{url}}\" endpoint": "Pustite prazno to include all models from \"{{url}}\" endpoint", "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Pustite prazno to include all models from \"{{url}}/api/tags\" endpoint", @@ -1342,39 +1559,51 @@ "Leave empty to use the default config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)": "Pustite prazno to use the privzeto config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/websearch/search#yandex.cloud.searchapi.v2.websearchrequest)", "Leave empty to use the default model (voxtral-mini-latest).": "Pustite prazno to use the privzeto model (voxtral-mini-latest).", "Leave empty to use the default prompt, or enter a custom prompt": "Pustite prazno to use the privzeto 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.", "Legacy": "Starejše", + "Let speech interrupt the assistant during a voice call.": "", + "Let users rate assistant responses.": "", "lexical": "lexical", "License": "Licenca", "Lifecycle JSON": "Lifecycle JSON", + "Lifetime tokens": "", "Lift List": "Lift List", "Light": "Svetlo", + "Limit API keys to configured endpoints.": "", "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).", - "Limits the number of concurrent embedding requests. Set to 0 for unlimited.": "Limits the number of concurrent embedding requests. Set to 0 for unlimited.", + "Limit how much draft text is sent for suggestion generation.": "", + "Limit parallel web loader requests.": "", + "Link OAuth sign-ins to existing accounts with the same email.": "", "Linkup API Key": "Linkup API Key", "List": "Seznam", "List calendars, search, create, update, and delete calendar events": "List calendars, search, create, update, and delete calendar events", "Listening...": "Poslušanje ...", + "LiteLLM": "", "Live": "V živo", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Veliki jezikovni modeli lahko delajo napake. Preverite pomembne informacije.", "Loaded": "Naloženo", "Loader": "Nalagalnik", "Loading Kokoro.js...": "Loading Kokoro.js...", + "Loading policy...": "", + "Loading release notes...": "", "Loading...": "Nalaganje ...", "local": "lokalno", "Local": "Lokalno", "Local Task Model": "Lokalni model za naloge", "Location": "Lokacija", "Location access not allowed": "Dostop do lokacije ni dovoljen", + "Longest active chat": "", + "Longest streak": "", "Lost": "Izgubljeno", "Low": "Nizko", - "Lower the context compaction token threshold for this model. The global context compaction threshold remains the maximum.": "Lower the context compaction token threshold for this model. The global context compaction threshold remains the maximum.", "LTR": "Od leve proti desni", "Made by Open WebUI Community": "Made by Open WebUI Community", + "Make Default": "", "Make password visible in the user interface": "Make password visible in the user interface", - "Make sure to export a workflow.json file as API format from ComfyUI.": "Make sure to export a workflow.json file as API format from ComfyUI.", + "Make Private": "", + "Make Public": "", "Male": "Moški", "Manage": "Upravljaj", "Manage Connections": "Upravljaj povezave", @@ -1384,21 +1613,38 @@ "Manage Ollama": "Upravljaj Ollama", "Manage Ollama API Connections": "Upravljaj povezave Ollama API", "Manage OpenAI API Connections": "Upravljaj povezave OpenAI API", - "Manage Pipelines": "Upravljaj cevovode", - "Manage Tool Servers": "Upravljaj strežnike orodij", - "Manage your account information.": "Upravljajte podatke svojega računa.", + "Map LDAP groups to Open WebUI groups.": "", + "Map OAuth claims to Open WebUI groups.": "", + "Map OAuth claims to Open WebUI roles.": "", + "Map workflow node inputs used for image edits.": "", + "Map workflow node inputs used for image generation.": "", "Mapped Source": "Mapped Source", "March": "marec", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown Header Text Splitter", + "Max background": "", + "Max concurrent": "", + "Max iterations": "", + "Max output": "", "Max Speakers": "Max Speakers", "Max tokens to retrieve (1024-32768, default 8192)": "Max tokens to retrieve (1024-32768, default 8192)", "Max Upload Count": "Največje število nalaganj", "Max Upload Size": "Največja velikost nalaganja", "Maximum characters to return from fetched URLs. Leave empty for no limit.": "Maximum characters to return from fetched URLs. Leave empty for no limit.", + "Maximum concurrent embedding requests. Set to 0 for unlimited.": "", + "Maximum file size in MB. Leave empty for unlimited.": "", "Maximum number of files allowed per folder.": "Maximum number of files allowed per folder.", "Maximum number of files per folder is {{max}}.": "Maximum number of files per folder is {{max}}.", + "Maximum number of files that can be used at once in chat.": "", + "Maximum number of hybrid results sent to the reranker.": "", + "Maximum number of retrieved chunks returned to the model.": "", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximum of 3 models can be downloaded simultaneously. Please try again later.", + "Maximum runtime in seconds before execution is stopped.": "", + "Maximum size for each text chunk.": "", + "Maximum time in seconds to wait for MinerU API responses.": "", + "Maximum time to wait while loading web content.": "", "May": "maj", "MBR": "MBR", "MCP": "MCP", @@ -1417,12 +1663,15 @@ "Memory System Context": "Sistemski kontekst pomnilnika", "Memory updated successfully": "Pomnilnik je uspešno posodobljen", "Merge Accounts by Email": "Merge Accounts by Email", + "Merge chunks smaller than this threshold when possible. Set to 0 to disable merging.": "", "Merge Responses": "Merge Responses", "Merged Response": "Merged Response", "Message": "Sporočilo", "Message counts and response timestamps": "Message counts and response timestamps", "Message counts are based on assistant responses.": "Message counts are based on assistant responses.", + "Message Rating": "", "Message rating should be enabled to use this feature": "Message rating should be enabled to use this feature", + "Message shown before web search runs.": "", "Message text...": "Besedilo sporočila ...", "messages": "sporočila", "Messages": "Sporočila", @@ -1435,15 +1684,16 @@ "Microsoft Web IQ API Key": "Microsoft Web IQ API Key", "min": "min", "MinerU": "MinerU", + "MinerU API endpoint for the selected mode.": "", "MinerU API Key required for Cloud API mode.": "MinerU API Key required for Cloud API mode.", "Mistral OCR": "Mistral OCR", "Mistral OCR API Key required.": "Mistral OCR API Key required.", + "Mistral OCR service endpoint.": "", "MistralAI": "MistralAI", "Mo_day_of_week": "Mo_day_of_week", "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' has been successfully downloaded.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' is already in queue for downloading.", - "Model {{modelId}} not found": "Model {{modelId}} not found", "Model {{modelName}} deleted successfully": "model {{modelName}} je uspešno izbrisano", "Model {{modelName}} is not vision capable": "Model {{modelName}} is not vision capable", "Model {{name}} is now {{status}}": "Model {{name}} is now {{status}}", @@ -1451,30 +1701,43 @@ "Model {{name}} is now visible": "Model {{name}} is now visible", "Model accepts file inputs": "Model accepts file inputs", "Model accepts image inputs": "Model accepts image inputs", + "Model added to pinned models": "", + "Model added to selected models": "", "Model can access Open Terminal for command execution and file management": "Model can access Open Terminal for command execution and file management", "Model can execute code and perform calculations": "Model can execute code and perform calculations", "Model can generate images based on text prompts": "Model can generate images based on text prompts", "Model can search the web for information": "Model can search the web for information", "Model Capabilities": "Zmožnosti modela", "Model created successfully!": "Model je uspešno ustvarjen!", + "Model Defaults": "", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Model filesystem path detected. Model shortname is required for update, cannot continue.", "Model Filtering": "Filtriranje modelov", "Model ID": "ID modela", "Model ID is required.": "ID modela je obvezen.", "Model IDs": "ID-ji modelov", + "Model is now private": "", + "Model is now public": "", "Model Name": "Ime modela", "Model name already exists, please choose a different one": "Ime modela že obstaja, izberite drugo ime", "Model Name is required.": "Ime modela je obvezno.", + "Model name used by Document Intelligence.": "", "Model names and usage frequency": "Model names and usage frequency", "Model not found": "Modela ni mogoče najti", "Model not selected": "Model ni izbran", + "Model order saved successfully": "", + "Model parameters": "", "Model Parameters": "Parametri modela", "Model Params": "Parametri modela", "Model Permissions": "Dovoljenja modela", + "Model removed from pinned models": "", + "Model removed from selected models": "", "Model responses or outputs": "Model responses or outputs", "Model unloaded successfully": "Model je uspešno odstranjen iz pomnilnika", "Model updated successfully": "Model je uspešno posodobljen", "Model Usage": "Uporaba modela", + "Model used to generate embeddings. Reindex knowledge after changing this.": "", + "Model used to rerank retrieved results.": "", + "Model-specific context compaction thresholds cannot exceed this token limit.": "", "Model(s) do not support file upload": "Model(s) do not support file upload", "Modelfile Content": "Modelfile Content", "Models": "Modeli", @@ -1492,7 +1755,9 @@ "More Concise": "Bolj jedrnato", "More options": "Več možnosti", "More Options": "Več možnosti", + "Most used tools": "", "Move": "Premakni", + "Move every chat into the archive after confirmation.": "", "Moved {{name}}": "Premaknjeno: {{name}}", "Multipart Upload": "Multipart Upload", "Mute": "Utišaj", @@ -1507,36 +1772,41 @@ "Native mode (default) leverages the model's built-in tool-calling capabilities. Legacy mode works with a wider range of models by calling tools once before execution via prompt injection.": "Native mode (default) leverages the model's built-in tool-calling capabilities. Legacy mode works with a wider range of models by calling tools once before execution via prompt injection.", "Never": "Nikoli", "New": "Novo", - "New Automation": "Nova avtomatizacija", "New Button": "Nov gumb", "New calendar": "Nov koledar", "New Calendar": "Nov koledar", + "New chat": "", "New Chat": "Nov pogovor", "New directory": "Nova mapa", "New Directory": "Nova mapa", - "New Event": "Nov dogodek", "New File": "Nova datoteka", "New Folder": "Nova mapa", "New Function": "Nova funkcija", "New Group": "Nova skupina", - "New Knowledge": "Nova baza znanja", - "New Model": "Nov model", "New Note": "Nov zapisek", "New Password": "Novo geslo", - "New Prompt": "Nov poziv", - "New Skill": "Nova veščina", + "New Sign Ups": "", "New Temporary Chat": "Nov začasni pogovor", "New Terminal": "Nov terminal", "New Tool": "Novo orodje", "New Webhook": "Nov webhook", "new-channel": "new-channel", "Next message": "Naslednje sporočilo", + "Next month": "", + "Next page": "", "Next run": "Naslednji zagon", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Ni dodeljenih dostopov. Zasebno samo za vas.", + "No actions found": "", "No activity data": "Ni podatkov o dejavnosti", "No additional headers are sent unless configured.": "Ni dodatni headers are sent unless configured.", "No authentication": "Brez avtentikacije", "No automations found": "Ni najdenih avtomatizacij", + "No chat alerts": "", + "No chat history": "", + "No chat to compact": "", + "No chat to fork": "", "No chats found": "Ni najdenih pogovorov", "No chats found for this user.": "Ni chats found for this user.", "No chats found.": "Ni chats found.", @@ -1546,9 +1816,9 @@ "No conversation to save": "Ni conversation to save", "No data": "Ni podatkov", "No data found": "Ni najdenih podatkov", + "No description": "", "No distance available": "Ni distance available", "No event webhooks configured.": "Ni event webhooks configured.", - "No execution logs available yet": "Ni execution logs available yet", "No expiration can pose security risks.": "Ni expiration can pose security risks.", "No external knowledge sources configured.": "Ni zunanji knowledge sources configured.", "No feedback found": "Ni najdenih povratnih informacij", @@ -1556,6 +1826,8 @@ "No files found": "Ni najdenih datotek", "No files in this knowledge base.": "Ni files in this knowledge base.", "No files yet. Upload files or run Python code to create them.": "Ni files yet. upload files or run python code to create them.", + "No filters found": "", + "No folders": "", "No functions found": "Ni najdenih funkcij", "No groups found": "Ni najdenih skupin", "No history available": "Zgodovina ni na voljo", @@ -1566,14 +1838,17 @@ "No knowledge bases found.": "Ni najdenih baz znanja.", "No knowledge found": "Ni najdene baze znanja", "No limit": "Brez omejitve", - "No memories to clear": "Ni pomnilnikov za brisanje", + "No matches": "", + "No model data": "", "No model IDs": "Ni ID-jev modelov", + "No model usage found": "", "No models accessible": "Ni dostopnih modelov", "No models available": "Ni razpoložljivih modelov", "No models found": "Ni najdenih modelov", "No models selected": "Ni izbranih modelov", "No Notes": "Ni zapiskov", "No notes found": "Ni najdenih zapiskov", + "No notification targets configured.": "", "No one": "Nihče", "No output items": "Ni izhodnih elementov", "No pinned messages": "Ni pinned messages", @@ -1581,6 +1856,7 @@ "No Repeat": "Ni repeat", "No results": "Ni rezultatov", "No results found": "Ni najdenih rezultatov", + "No runs yet": "", "No search query generated": "Iskalna poizvedba ni bila ustvarjena", "No servers detected": "Ni servers detected", "No skills found": "Ni najdenih veščin", @@ -1592,6 +1868,8 @@ "No tool server connections configured.": "Ni tool server connections configured.", "No tools accessible": "Ni dostopnih orodij", "No tools found": "Ni najdenih orodij", + "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Ni najdenih uporabnikov.", "No valves": "Ni valves", "No valves to update": "Ni valves to update", @@ -1605,23 +1883,30 @@ "Not scheduled": "Ni načrtovano", "Note": "Zapisek", "Note deleted successfully": "Zapisek je uspešno izbrisan", - "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.", + "Note Menu": "", "Notes": "Zapiski", "Notes Public Sharing": "Notes Public Sharing", "Notes Sharing": "Notes Sharing", + "Nothing to compact": "", "Notification Sound": "Zvok obvestila", - "Notification Webhook": "Webhook za obvestila", + "Notification Targets": "", "Notifications": "Obvestila", "November": "november", + "Number of items processed per embedding batch.": "", + "Number of results processed per reranking batch.": "", "OAuth": "OAuth", "OAuth / OIDC": "OAuth / OIDC", "OAuth 2.1": "OAuth 2.1", "OAuth 2.1 (Static)": "OAuth 2.1 (Static)", + "OAuth client identifier from the provider.": "", + "OAuth client secret from the provider.": "", "OAuth ID": "OAuth ID", "OAuth Resource Parameter": "OAuth Resource Parameter", "OAuth Scopes": "OAuth Scopes", + "OAuth scopes requested during sign-in.": "", "OAuth Server URL": "OAuth Server URL", "OAuth session disconnected": "Seja OAuth je prekinjena", + "OAuth Signup": "", "October": "oktober", "Off": "Izklopljeno", "Okay, Let's Go!": "V redu, začnimo!", @@ -1631,6 +1916,7 @@ "Ollama API": "Ollama API", "Ollama API settings updated": "Ollama API settings updated", "Ollama Cloud API Key": "Ollama Cloud API Key", + "Ollama endpoint used for embeddings.": "", "Ollama Version": "Ollama Version", "Omit": "Izpusti", "On": "Vklopljeno", @@ -1644,14 +1930,21 @@ "Only alphanumeric characters and hyphens are allowed in the command string.": "Only alphanumeric characters and hyphens are allowed in the command string.", "Only can be triggered when the chat input is in focus.": "Only can be triggered when the chat input is in focus.", "Only collections can be edited, create a new knowledge base to edit/add documents.": "Only collections can be edited, create a new knowledge base to edit/add documents.", + "Only install functions from sources you trust.": "", + "Only install tools from sources you trust.": "", "Only invited users can access": "Dostop imajo samo povabljeni uporabniki", - "Only markdown files are allowed": "Dovoljene so samo datoteke Markdown", + "Only return documents with a score greater than or equal to this value.": "", "Only select users and groups with permission can access": "Only select users and groups with permission can access", "Only sync new/updated chats": "Only sync new/updated chats", + "Only when away": "", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Oops! Looks like the URL is invalid. Please double-check and try again.", "Oops! There are files still uploading. Please wait for the upload to complete.": "Oops! There are files still uploading. Please wait for the upload to complete.", "Oops! There was an error in the previous response.": "Oops! There was an error in the previous response.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.", + "Open": "", + "Open automation": "", + "Open create menu": "", + "Open detail blocks by default.": "", "Open file": "Odpri datoteko", "Open in full screen": "Odpri v celozaslonskem načinu", "Open in new tab": "Odpri v novem zavihku", @@ -1660,9 +1953,13 @@ "Open Modal To Manage Floating Quick Actions": "Odpri Modal To Manage Floating Quick Actions", "Open Modal To Manage Image Compression": "Odpri Modal To Manage slika Compression", "Open Model Selector": "Odpri izbirnik modelov", + "Open note": "", "Open Settings": "Odpri nastavitve", "Open Sidebar": "Odpri stransko vrstico", "Open Terminal": "Odpri terminal", + "Open the changelog modal after sign-in when enabled.": "", + "Open the file browser after selecting a terminal.": "", + "Open the file manager for uploaded files.": "", "Open User Profile Menu": "Odpri meni uporabniškega profila", "Open WebUI can use tools provided by any OpenAPI server.": "Odpri WebUI can use tools provided by any OpenAPI server.", "Open WebUI uses faster-whisper internally.": "Odpri WebUI uses faster-whisper internally.", @@ -1671,17 +1968,17 @@ "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Odpri WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})", "OpenAI": "OpenAI", "OpenAI API": "OpenAI API", - "OpenAI API Base URL": "OpenAI API Base URL", - "OpenAI API Key": "OpenAI API Key", "OpenAI API Key is required.": "OpenAI API ključ je obvezno.", "OpenAI API settings updated": "OpenAI API settings updated", - "OpenAI API Version": "OpenAI API Version", "OpenAI URL/Key required.": "OpenAI URL/Key required.", + "OpenAI-compatible embeddings endpoint.": "", "OpenAPI": "OpenAPI", "OpenAPI Spec": "OpenAPI Spec", "openapi.json URL or Path": "openapi.json URL or Path", + "OpenID discovery URL for this provider.": "", "optional": "neobvezno", "Optional": "Neobvezno", + "Optional API key for Ollama requests.": "", "or": "ali", "Ordered List": "Oštevilčen seznam", "Other": "Drugo", @@ -1690,18 +1987,24 @@ "OUTPUT": "IZHOD", "Output format": "Izhodna oblika", "Output Format": "Izhodna oblika", + "Overlap preserved between neighboring chunks.": "", + "Override the Gemini image generation endpoint.": "", "Overview": "Pregled", "PaddleOCR-vl": "PaddleOCR-vl", "PaddleOCR-vl API URL required.": "PaddleOCR-vl API URL required.", + "PaddleOCR-vl service endpoint.": "", "page": "stran", "Page": "Stran", - "Page mode creates one document per page. Single mode combines all pages into one document for better chunking across page boundaries.": "Page mode creates one document per page. Single mode combines all pages into one document for better chunking across page boundaries.", + "Page mode creates one document per page. Single mode keeps pages together for chunking across boundaries.": "", "Paginate": "Paginate", "Parameters": "Parametri", "Parent message not found": "Nadrejeno sporočilo ni najdeno", "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.", + "Passthrough params": "", "Password": "Geslo", + "Password for the bind DN.": "", "Passwords do not match.": "Gesli se ne ujemata.", + "Paste inserted prompts as rich text when possible.": "", "Paste Large Text as File": "Paste Large Text as File", "Path": "Pot", "Path copied": "Pot je kopirana", @@ -1710,11 +2013,14 @@ "PDF Extract Images (OCR)": "PDF Extract Images (OCR)", "PDF Loader Mode": "PDF Loader Mode", "pdf, docx, pptx, xlsx": "pdf, docx, pptx, xlsx", + "Peak tokens": "", "pending": "v teku", "Pending": "V teku", "Pending Accounts": "Računi v čakanju", "Pending User Overlay Content": "Pending User Overlay Content", "Pending User Overlay Title": "Pending User Overlay Title", + "Percentage of recent messages to keep after older messages are summarized.": "", + "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Dovoljenje za dostop do predstavnostnih naprav je zavrnjeno", "Permission denied when accessing microphone": "Dovoljenje za dostop do mikrofona je zavrnjeno", "Permission denied when accessing microphone: {{error}}": "Permission denied when accessing microphone: {{error}}", @@ -1725,23 +2031,25 @@ "Perplexity Search API URL": "Perplexity Search API URL", "Perplexity Search Context Usage": "Perplexity Search Context Usage", "Persistent": "Trajno", + "Personal": "", "Personalization": "Prilagoditev", "Picture Claim": "Picture Claim", "Pin": "Pripni", "Pin to Sidebar": "Pripni v stransko vrstico", "Pinned": "Pripeto", "Pinned Messages": "Pripeta sporočila", - "Pinned Models": "Pinned Models", - "Pioneer insights": "Pioneer insights", "Pipe": "Pipe", + "Pipeline": "", "Pipeline deleted successfully": "Cevovod je uspešno izbrisan", "Pipeline downloaded successfully": "Cevovod je uspešno prenesen", + "Pipeline URL": "", "Pipelines": "Cevovodi", - "Pipelines are a plugin system with arbitrary code execution —": "Pipelines are a plugin system with arbitrary code execution —", + "Pipelines are a plugin system with arbitrary code execution.": "", "Pipelines Not Detected": "Pipelines Not Detected", - "Pipelines Valves": "Pipelines Valves", + "Place selected suggestion text into the composer.": "", "Plain text (.md)": "Plain text (.md)", "Plain text (.txt)": "Plain text (.txt)", + "Play assistant responses aloud automatically.": "", "Playground": "Igrišče", "Playwright Timeout (ms)": "Playwright Timeout (ms)", "Playwright WebSocket URL": "Playwright WebSocket URL", @@ -1764,20 +2072,29 @@ "Please select a valid JSON file": "Izberite veljavno datoteko JSON", "Please select at least one user for Direct Message channel.": "Please select at least one user for Direct Message channel.", "Please wait until all files are uploaded.": "Počakajte, da se naložijo vse datoteke.", + "Policy changes apply to newly provisioned terminals. Refresh matching terminals to apply them to existing terminals.": "", "Policy ID": "ID pravilnika", "Policy ID is required": "ID pravilnika je obvezen", + "Policy is still loading": "", "Port": "Vrata", "Ports": "Vrata", "Positive attitude": "Pozitiven odnos", "Prefer not to say": "Ne želim povedati", + "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Predpona ID-ja", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable", + "Preparing download...": "", + "Press keys...": "", "Prevent File Creation": "Prevent File Creation", "Preview": "Predogled", "Preview Access": "Dostop za predogled", "Previous 30 days": "Prejšnjih 30 dni", "Previous 7 days": "Prejšnjih 7 dni", "Previous message": "Prejšnje sporočilo", + "Previous month": "", + "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Zasebno", "Private conversation between selected users": "Private conversation between selected users", "Production version updated": "Produkcijska različica je posodobljena", @@ -1786,17 +2103,26 @@ "Prompt Autocompletion": "Samodokončanje poziva", "Prompt Content": "Vsebina poziva", "Prompt created successfully": "Poziv je uspešno ustvarjen", + "Prompt Menu": "", "Prompt Name": "Ime poziva", "Prompt Suggestions": "Predlogi pozivov", "Prompt Template": "Predloga poziva", + "Prompt template used when retrieved context is injected.": "", "Prompt updated successfully": "Poziv je uspešno posodobljen", "Prompts": "Pozivi", "Prompts Access": "Dostop do pozivov", "Prompts Public Sharing": "Javno deljenje pozivov", "Prompts Sharing": "Deljenje pozivov", + "Provide the --api-auth username and password when required.": "", "Provider": "Ponudnik", + "Provider groups blocked from signing in.": "", "Provider Name": "Ime ponudnika", + "Provider roles allowed to sign in.": "", + "Provider roles that grant admin access.": "", "Provider URL": "URL ponudnika", + "Provider used to generate document embeddings.": "", + "Provider used to rerank hybrid search results.": "", + "Proxy URL used for Youtube loader requests.": "", "Public": "Javno", "Pull \"{{searchValue}}\" from Ollama.com": "Pull \"{{searchValue}}\" from Ollama.com", "Pull a model from Ollama.com": "Pull a model from Ollama.com", @@ -1804,23 +2130,25 @@ "Pyodide file browser": "Pyodide file browser", "Query Generation Prompt": "Poziv za ustvarjanje poizvedbe", "Querying": "Poizvedovanje", + "Queue outgoing messages instead of interrupting active responses.": "", "Quick Actions": "Hitra dejanja", "RAG Template": "Predloga RAG", "Ran {{COUNT}} analyses": "Ran {{COUNT}} analyses", "Ran {{COUNT}} analysis": "Ran {{COUNT}} analysis", "Rate {{rating}} out of 10": "Rate {{rating}} out of 10", "Rating": "Ocena", - "Re-rank models by topic similarity": "Re-rank models by topic similarity", "Read": "Preberi", "Read Aloud": "Preberi na glas", "Read more →": "Preberi več →", "Read only": "Samo za branje", "Read Only": "Samo za branje", + "Read the docs": "", "Read-Only Access": "Dostop samo za branje", "Reason": "Razlog", "Reasoning Effort": "Raven sklepanja", "Reasoning Tags": "Oznake sklepanja", "Reasoning text...": "Besedilo sklepanja ...", + "Rebuild vectors for existing knowledge files.": "", "Receives matching events across the instance, including system/config events and events associated with any user.": "Receives matching events across the instance, including system/config events and events associated with any user.", "Receives matching events that are not associated with a user.": "Receives matching events that are not associated with a user.", "Receives matching user-associated events only when the actor, user subject, or user data matches these users or current group members. System/config events are not sent.": "Receives matching user-associated events only when the actor, user subject, or user data matches these users or current group members. System/config events are not sent.", @@ -1834,8 +2162,13 @@ "Reference Chats": "Reference Chats", "Refresh": "Osveži", "Refresh requested: {{count}} terminal(s)_one": "Osveži requested: {{count}} terminal(s)_one", + "Refresh requested: {{count}} terminal(s)_two": "", + "Refresh requested: {{count}} terminal(s)_few": "", "Refresh requested: {{count}} terminal(s)_other": "Osveži requested: {{count}} terminal(s)_other", "Refresh Terminals": "Osveži terminale", + "Refresh the account email from OAuth on sign-in.": "", + "Refresh the account name from OAuth on sign-in.": "", + "Refresh the profile picture from OAuth on sign-in.": "", "Refreshing...": "Osveževanje ...", "Refused when it shouldn't have": "Refused when it shouldn't have", "Regenerate": "Ustvari znova", @@ -1857,21 +2190,25 @@ "Remove": "Odstrani", "Remove {{MODELID}} from list.": "Odstrani {{MODELID}} from list.", "Remove action": "Odstrani dejanje", + "Remove existing OCR text and rerun OCR when Force OCR is off.": "", "Remove file": "Odstrani datoteka", "Remove File": "Odstrani datoteka", "Remove from favorites": "Odstrani iz priljubljenih", "Remove image": "Odstrani slika", - "Remove Model": "Odstrani model", + "Remove Pinned Model": "", + "Remove prompt suggestion": "", + "Remove Selected Model": "", "Removing {{count}} stale files..._one": "Removing {{count}} stale files..._one", + "Removing {{count}} stale files..._two": "", + "Removing {{count}} stale files..._few": "", "Removing {{count}} stale files..._other": "Removing {{count}} stale files..._other", "Rename": "Preimenuj", "Renamed to {{name}}": "Renamed to {{name}}", "Render Markdown in Assistant Messages": "Render Markdown in Assistant Messages", "Render Markdown in Previews": "Render Markdown in Previews", "Render Markdown in User Messages": "Render Markdown in User Messages", - "Reorder Models": "Reorder Models", + "Render messages in compact bubble containers.": "", "Repeat": "Repeat", - "Repeats": "Repeats", "Reply": "Odgovori", "Reply in Thread": "Reply in Thread", "Reply to thread...": "Reply to thread...", @@ -1886,8 +2223,8 @@ "Reset": "Ponastavi", "Reset All Models": "Ponastavi vse modele", "Reset all permissions to their initial configuration values": "Ponastavi all permissions to their initial configuration values", + "Reset Defaults": "", "Reset group permissions to match the current default user permissions": "Ponastavi group permissions to match the trenutni privzeto user permissions", - "Reset Image": "Ponastavi slika", "Reset knowledge base?": "Ponastavi knowledge base?", "Reset persisted files": "Ponastavi persisted files", "Reset to Defaults": "Ponastavi to Defaults", @@ -1895,30 +2232,48 @@ "Reset Vector Storage/Knowledge": "Ponastavi Vector Storage/baza znanja", "Reset view": "Ponastavi view", "Response": "Odgovor", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.", - "Response splitting": "Response splitting", + "Response Splitting": "", "Response Watermark": "Response Watermark", "Responses": "Odgovori", "Restart": "Ponovni zagon", + "Restrict or exclude domains using a comma-separated list.": "", "Result": "Result", "RESULT": "RESULT", + "Retained Messages": "", "Retrieval": "Retrieval", "Retrieval Query Generation": "Retrieval Query Generation", "Retrieved {{count}} sources": "Retrieved {{count}} sources", "Retrieved {{count}} sources_one": "Retrieved {{count}} sources_one", + "Retrieved {{count}} sources_two": "", + "Retrieved {{count}} sources_few": "", "Retrieved {{count}} sources_other": "Retrieved {{count}} sources_other", "Retrieved 1 source": "Retrieved 1 source", + "Retry": "", + "Review and manage chats you have shared.": "", + "Rewrite the selected text.": "", + "Rewrite user requests for knowledge retrieval.": "", + "Rewrite user requests into web-search queries.": "", + "Rewrites user intent into an image-generation prompt.": "", "Rich Text Input for Chat": "Rich Text Input for Chat", "Role": "Vloga", + "Role assigned to new users when they create an account.": "", + "Role Mapping": "", "Roles Claim": "Roles Claim", "RTL": "Od desne proti levi", "Run": "Zaženi", + "Run AI on your own terms. Connect any model, extend with code, and protect what matters without compromise. Your models, your data, your machine, wherever you open it.": "", "Run All": "Zaženi All", + "Run embedding tasks concurrently to speed up processing.": "", "Run now": "Zaženi now", "Run Now": "Zaženi Now", + "Run OCR on all PDF pages, even pages with embedded text.": "", "Running": "Izvaja se", + "Running Open WebUI for a team?": "", "Running...": "Izvaja se ...", - "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.", + "runs": "", + "Runs": "", "Sa_day_of_week": "Sa_day_of_week", "Save": "Shrani", "Save & Create": "Shrani in ustvari", @@ -1926,11 +2281,15 @@ "Save As Copy": "Shrani kot kopijo", "Save Chat": "Shrani pogovor", "Saved": "Shranjeno", + "Saved Memories": "", "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through", + "Saving...": "", "Schedule": "Schedule", "Scheduled time must be in the future": "Scheduled time must be in the future", "Scopes": "Scopes", "Scroll On Branch Change": "Scroll On Branch Change", + "Scroll to bottom": "", + "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Scroll to Top", "Search": "Iskanje", "Search a model": "Poišči model", @@ -1946,6 +2305,7 @@ "Search Files": "Search Files", "Search filters": "Search filters", "Search Filters": "Search Filters", + "Search folders": "", "search for archived chats": "search for archived chats", "search for folders": "search for folders", "search for pinned chats": "search for pinned chats", @@ -1955,6 +2315,7 @@ "Search Groups": "Search Groups", "Search In Models": "Search In Models", "Search Knowledge": "Išči bazo znanja", + "Search Limits": "", "Search Memories": "Search Memories", "Search Models": "Išči modele", "Search Notes": "Search Notes", @@ -1979,11 +2340,13 @@ "Searching the web": "Searching the web", "Searxng Query URL": "Searxng Query URL", "Searxng search language (all, en, es, de, fr, etc.)": "Searxng search language (all, en, es, de, fr, etc.)", + "Secrets": "", "See readme.md for instructions": "Za navodila glejte readme.md", "See what's new": "See what's new", "Seed": "Seed", "Select": "Izberi", "Select {{modelName}} model": "Izberi {{modelName}} model", + "Select a .py file": "", "Select a base model (e.g. llama3, gpt-4o)": "Izberi a base model (e.g. llama3, gpt-4o)", "Select a conversation to preview": "Izberi a conversation to preview", "Select a engine": "Izberi a engine", @@ -2000,33 +2363,51 @@ "Select a theme": "Izberi a theme", "Select a tool": "Izberite orodje", "Select a voice": "Izberi a voice", + "Select Action": "", "Select All": "Izberi All", "Select an auth method": "Izberi an auth method", "Select an embedding model engine": "Izberi an embedding model engine", "Select an engine": "Izberi an engine", + "Select an installed pipeline to configure or remove.": "", "Select an Ollama instance": "Izberi an Ollama instance", "Select an option": "Izberi an option", "Select an output format": "Izberi an output format", "Select dtype": "Izberi dtype", "Select Engine": "Izberi Engine", + "Select Filter": "", + "Select how audio is sent to the OpenAI-compatible endpoint.": "", + "Select how Open WebUI authenticates with the Jupyter server.": "", "Select how to split message text for TTS requests": "Izberi how to split message text for TTS requests", "Select Knowledge": "Izberi baza znanja", "Select Method": "Izberi Method", "Select model": "Izberi model", "Select only one model to call": "Izberite samo en model za klic", + "Select Skill": "", + "Select the Gemini endpoint method to call.": "", + "Select the local model precision used by Kokoro.js.": "", + "Select the Pipelines server to manage.": "", + "Select Tool": "", "Select view": "Izberi view", + "Selected": "", "Selected model: {{modelName}}": "Selected model: {{modelName}}", "Selected model(s) do not support image inputs": "Selected model(s) do not support image inputs", - "Selected Models": "Selected Models", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantic", "Send": "Pošlji", "Send a Message": "Send a Message", "Send events for": "Send events for", + "Send extra JSON parameters with each AUTOMATIC1111 request.": "", + "Send extra JSON parameters with each image generation request.": "", "Send message": "Send message", + "Send notifications to configured webhook targets": "", "Send now": "Send now", + "Send PDFs as base64 data URLs instead of uploading first.": "", "Send product events as JSON to external services. Chat destinations receive readable messages.": "Send product events as JSON to external services. Chat destinations receive readable messages.", - "Send the PDF as a base64 data URL instead of uploading it first.": "Send the PDF as a base64 data URL instead of uploading it first.", + "Send Test": "", + "Send transcribed voice input immediately after speech recognition finishes.": "", + "Send users directly to the OAuth provider from the sign-in page.": "", "Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.", + "Separate output by page with page markers.": "", "September": "september", "SerpApi API Key": "SerpApi API Key", "SerpApi Engine": "SerpApi Engine", @@ -2040,16 +2421,23 @@ "Service Account": "Service Account", "Session": "Seja", "Session expired. Please sign in again.": "Session expired. Please sign in again.", + "Set a local zoom level for the app interface.": "", + "Set a model-specific context compaction token threshold. When set, this overrides the global threshold up to the global cap.": "", + "Set a speech recognition language or leave it blank to detect automatically.": "", "Set as default": "Nastavi kot privzeto", + "Set as Pinned Model": "", "Set as Production": "Set as Production", + "Set as Selected Model": "", "Set embedding model": "Set embedding model", "Set embedding model (e.g. {{model}})": "Set embedding model (e.g. {{model}})", "Set reranking model (e.g. {{model}})": "Set reranking model (e.g. {{model}})", - "Set the default models that are automatically selected for all users when a new chat is created.": "Set the default models that are automatically selected for all users when a new chat is created.", - "Set the models that are automatically pinned to the sidebar for all users.": "Set the models that are automatically pinned to the sidebar for all users.", + "Set the birth date saved with your profile.": "", + "Set the default system prompt for new chats.": "", + "Set the display name shown across your account.": "", "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.", "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.", "Set Voice": "Set Voice", + "Set web search availability for new chats.": "", "Set whisper model": "Set whisper model", "Set your status": "Set your status", "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.", @@ -2062,27 +2450,41 @@ "Settings": "Nastavitve", "Settings Permissions": "Settings Permissions", "Settings saved successfully!": "Settings saved successfully!", + "Shapes the short label generated for each chat.": "", "Share": "Deli", "Share Chat": "Deli pogovor", "Share link copied to clipboard.": "Deli link copied to clipboard.", "Share to Open WebUI Community": "Deli s skupnostjo Open WebUI", "Share your background and interests": "Deli your background and interests", + "Share your current location with features that can use it.": "", "Shared": "Deljeno", "Shared Chats": "Deljeni pogovori", + "Shared prompt for retrieval and web-search query rewriting.": "", "Shared with you": "Shared with you", "Sharing Permissions": "Sharing Permissions", "Show": "Prikaži", "Show \"What's New\" Modal on Login": "Prikaži \"What's Nov\" Modal on Login", - "Show Admin Details in Account Pending Overlay": "Prikaži skrbniške podrobnosti pri čakajočem računu", + "Show admin contact details while an account waits for approval.": "", "Show All": "Prikaži All", "Show all ({{COUNT}} characters)": "Prikaži all ({{COUNT}} characters)", + "Show emoji feedback in the call interface.": "", "Show Files": "Prikaži datoteke", "Show Files on Terminal Select": "Prikaži datoteke on terminal Select", + "Show formatting controls in the rich text composer.": "", "Show Formatting Toolbar": "Prikaži Formatting Toolbar", "Show image preview": "Prikaži image preview", "Show Model": "Prikaži model", + "Show more": "", + "Show or hide custom generation parameters.": "", + "Show or hide sensitive account secrets.": "", "Show Shortcuts": "Prikaži Shortcuts", + "Show suggested next questions after assistant responses.": "", + "Show the floating quick-action toolbar in chat.": "", + "Show the regenerate action menu for assistant responses.": "", + "Show update toasts to admins when new versions are available.": "", + "Show user status information in the app.": "", "Show your support!": "Prikaži your support!", + "Show your username label instead of You in chat bubbles.": "", "Showcased creativity": "Showcased creativity", "Showing all messages (user + assistant) per user.": "Showing all messages (user + assistant) per user.", "Sign in": "Prijava", @@ -2091,8 +2493,8 @@ "Sign Out": "Odjava", "Sign up": "Registracija", "Sign up to {{WEBUI_NAME}}": "Registracija v {{WEBUI_NAME}}", - "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.": "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.", "Signing in to {{WEBUI_NAME}}": "Signing in to {{WEBUI_NAME}}", + "simultaneous sub-agents": "", "Single": "Single", "Sink List": "Sink List", "sk-1234": "sk-1234", @@ -2102,6 +2504,7 @@ "Skill ID": "ID veščine", "Skill imported successfully": "Veščina je uspešno uvožena", "Skill Instructions": "Skill Instructions", + "Skill Menu": "", "Skill Name": "Ime veščine", "Skill updated successfully": "Veščina je uspešno posodobljena", "Skills": "Veščine", @@ -2109,7 +2512,8 @@ "Skills Public Sharing": "Skills Public Sharing", "Skills Sharing": "Skills Sharing", "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.", + "Skip to main content": "", + "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Something went wrong :/", "Sonar": "Sonar", "Sonar Deep Research": "Sonar Deep Research", @@ -2117,7 +2521,6 @@ "Sonar Reasoning": "Sonar Reasoning", "Sonar Reasoning Pro": "Sonar Reasoning Pro", "Sort": "Sort", - "Sort by": "Sort by", "Sougou Search API sID": "Sougou Search API sID", "Sougou Search API SK": "Sougou Search API SK", "Source": "Vir", @@ -2127,16 +2530,19 @@ "Speech-to-Text": "Speech-to-Text", "Speech-to-Text Engine": "Speech-to-Text Engine", "Speech-to-Text Language": "Speech-to-Text Language", - "Split documents by markdown headers before applying character/token splitting.": "Split documents by markdown headers before applying character/token splitting.", + "Split documents by markdown headers before character or token splitting.": "", + "Sponsor on GitHub": "", "Start a new conversation": "Start a new conversation", + "Start new chats as temporary unless changed.": "", "Start of the channel": "Start of the channel", "Start Tag": "Začetna oznaka", "Starting in {{count}} minutes_one": "Starting in {{count}} minutes_one", + "Starting in {{count}} minutes_two": "", + "Starting in {{count}} minutes_few": "", "Starting in {{count}} minutes_other": "Starting in {{count}} minutes_other", "Starting in 1 minute": "Starting in 1 minute", "Starting kernel...": "Starting kernel...", "Starting now": "Starting now", - "State": "State", "Status": "Stanje", "Status cleared successfully": "Status cleared successfully", "Status updated successfully": "stanje je uspešno posodobljeno", @@ -2144,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Steps", "Stop": "Ustavi", + "Stop camera": "", "Stop Download": "Stop Download", "Stop Generating": "Stop Generating", "Stop Sequence": "Zaporedje zaustavitve", @@ -2153,12 +2560,12 @@ "Streamable HTTP": "Streamable HTTP", "Strikethrough": "Strikethrough", "Strip Existing OCR": "Strip Existing 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.", "STT Model": "STT Model", "STT Settings": "STT Settings", "Stylized PDF Export": "Stylized PDF Export", "Su_day_of_week": "Su_day_of_week", "Sub Claim": "Sub Claim", + "Sub-agents": "", "Submit question": "Submit question", "Submit suggestion": "Submit suggestion", "Subtitle": "Subtitle", @@ -2166,10 +2573,16 @@ "Successfully imported {{userCount}} users.": "Successfully imported {{userCount}} users.", "Successfully updated.": "Uspešno posodobljeno.", "Suggest a change": "Suggest a change", + "Suggest completions while composing prompts.": "", + "Suggest completions while users type chat messages.": "", "Suggested": "Suggested", + "Suggested prompts": "", + "Summarize older chat history when the conversation context grows large.": "", + "Summarize this note.": "", "Support": "Podpora", "Support this plugin:": "Support this plugin:", "Supported MIME Types": "Supported MIME Types", + "Switch camera": "", "Switch to JSON editor": "Switch to JSON editor", "Switch to visual editor": "Switch to visual editor", "Sync": "Sync", @@ -2185,6 +2598,7 @@ "System": "Sistem", "System events only": "System events only", "System Instructions": "System Instructions", + "System prompt": "", "System Prompt": "Sistemski poziv", "Table": "Table", "Tag": "Oznaka", @@ -2194,6 +2608,8 @@ "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.", "Talk to Model": "Talk to Model", "Tap to interrupt": "Tap to interrupt", + "Target ID": "", + "Target ID for notify": "", "Task List": "Task List", "Task Management": "Task Management", "Task Model": "Model za naloge", @@ -2208,11 +2624,14 @@ "Terminal": "Terminal", "Terminal servers saved": "Terminal servers saved", "Test": "Test", + "Test must pass before a source is created.": "", + "Test notification sent.": "", "Test Query": "Test Query", "Test returned no results.": "Test returned no results.", "Test succeeded.": "Test succeeded.", "Test the source before creating it.": "Test the source before creating it.", "Test the source before saving it.": "Test the source before saving it.", + "Text output format returned by Marker.": "", "Text Splitter": "Text Splitter", "Text-to-Speech": "Text-to-Speech", "Text-to-Speech Engine": "Text-to-Speech Engine", @@ -2224,28 +2643,22 @@ "The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.", "The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "The evaluation leaderboard is based on the Elo rating system and is updated in real-time.", "The format to return a response in. Format can be json or a JSON schema.": "The format to return a response in. Format can be json or a JSON schema.", - "The height in pixels to compress images to. Leave empty for no compression.": "The height in pixels to compress images to. Leave empty for no compression.", "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.": "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.", "The LDAP attribute that maps to the mail that users use to sign in.": "The LDAP attribute that maps to the mail that users use to sign in.", "The LDAP attribute that maps to the username that users use to sign in.": "The LDAP attribute that maps to the username that users use to sign in.", - "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'.", + "The notify tool always sends to an enabled target, regardless of automatic event settings.": "", "The passwords you entered don't quite match. Please double-check and try again.": "The passwords you entered don't quite match. Please double-check and try again.", "The score should be a value between 0.0 (0%) and 1.0 (100%).": "The score should be a value between 0.0 (0%) and 1.0 (100%).", "The stream delta chunk size for the model. Increasing the chunk size will make the model respond with larger pieces of text at once.": "The stream delta chunk size for the model. Increasing the chunk size will make the model respond with larger pieces of text at once.", "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.", - "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5", - "The width in pixels to compress images to. Leave empty for no compression.": "The width in pixels to compress images to. Leave empty for no compression.", "Theme": "Tema", "There was an error syncing your stats. Please try again.": "There was an error syncing your stats. Please try again.", + "thinking, output_config": "", "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 won't appear in history and your messages will not be saved.": "This chat won't appear in history and your messages will not be saved.", "This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "This ensures that your valuable conversations are securely saved to your backend database. Thank you!", - "This feature is currently experimental and may not work as expected.": "This feature is currently experimental and may not work as expected.", - "This feature is experimental and may be modified or discontinued without notice.": "This feature is experimental and may be modified or discontinued without notice.", "This folder is empty": "This folder is empty", "This is a default user permission and will remain enabled.": "This is a default user permission and will remain enabled.", "This is an experimental feature, it may not function as expected and is subject to change at any time.": "This is an experimental feature, it may not function as expected and is subject to change at any time.", @@ -2259,7 +2672,6 @@ "This template contains multiple context placeholders ([context] or {{CONTEXT}}). Context will be injected at each occurrence.": "This template contains multiple context placeholders ([context] or {{CONTEXT}}). Context will be injected at each occurrence.", "This will delete": "To bo izbrisalo", "This will delete {{NAME}} and all its contents.": "This will delete {{NAME}} and all its contents.", - "This will delete all models including custom models": "This will delete all models including custom models", "This will delete all models including custom models and cannot be undone.": "This will delete all models including custom models and cannot be undone.", "This will permanently delete the calendar \"{{name}}\" and all its events. This action cannot be undone.": "This will permanently delete the calendar \"{{name}}\" and all its events. This action cannot be undone.", "This will remove all files and directories from this knowledge base. This action cannot be undone.": "This will remove all files and directories from this knowledge base. This action cannot be undone.", @@ -2269,13 +2681,17 @@ "Thought for {{DURATION}} seconds": "Thought for {{DURATION}} seconds", "Thought for less than a second": "Thought for less than a second", "Thread": "Thread", + "Through": "", "Thumbs up/down ratings from users on model responses": "Thumbs up/down ratings from users on model responses", "Tika": "Tika", + "Tika server endpoint used for content extraction.": "", + "Tika Server URL": "", "Tika Server URL required.": "Tika Server URL required.", "Tiktoken": "Tiktoken", "Time": "Time", "Time & Calculation": "Time & Calculation", "Timeout": "Timeout", + "Timer": "", "Title": "Naslov", "Title Auto-Generation": "Title Auto-Generation", "Title cannot be an empty string.": "Title cannot be an empty string.", @@ -2283,17 +2699,22 @@ "Title Generation Prompt": "Title Generation Prompt", "Title is required": "naslov je obvezno", "TLS": "TLS", + "TLS cipher list for LDAP connections.": "", "To access the available model names for downloading,": "To access the available model names for downloading,", "To access the GGUF models available for downloading,": "To access the GGUF models available for downloading,", "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.", "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "To attach knowledge base here, add them to the \"Knowledge\" workspace first.", "To learn more about available endpoints, visit our documentation.": "To learn more about available endpoints, visit our documentation.", + "To learn more about SpeechT5,": "", + "To see the available CMU Arctic speaker embeddings,": "", + "To select actions here, add them to the \"Functions\" workspace first.": "", + "To select default filters here, enable toggleable filters for this model first.": "", + "To select filters here, add them to the \"Functions\" workspace first.": "", "To select skills here, add them to the \"Skills\" workspace first.": "To select skills here, add them to the \"Skills\" workspace first.", - "To select toolkits here, add them to the \"Tools\" workspace first.": "To select toolkits here, add them to the \"Tools\" workspace first.", + "To select toolkits here, add them to the \"Tools\" workspace or enable a tool server first.": "", "Toast Notifications for New Updates": "Toast Notifications for New Updates", "Today": "Danes", "Today at": "Danes ob", - "Today at {{LOCALIZED_TIME}}": "Today at {{LOCALIZED_TIME}}", "Toggle {{COUNT}} sources": "Toggle {{COUNT}} sources", "Toggle 1 source": "Toggle 1 source", "Toggle details": "Toggle details", @@ -2303,9 +2724,12 @@ "Toggle status history": "Toggle status history", "Toggle whether current connection is active.": "Toggle whether current connection is active.", "Token": "Token", + "Token activity": "", + "Token Cap": "", "Token counts are estimates and may not reflect actual API usage": "Token counts are estimates and may not reflect actual API usage", "Token Threshold": "Token Threshold", "Tokenizer Model": "Tokenizer Model", + "Tokenizer model used for transformer token splitting.": "", "tokens": "tokens", "Tokens": "Tokens", "Too verbose": "Too verbose", @@ -2314,12 +2738,14 @@ "Tool Description": "Tool Description", "Tool ID": "Tool ID", "Tool imported successfully": "orodje je uspešno uvoženo", + "tool loops per sub-agent": "", + "Tool Menu": "", "Tool Name": "Tool Name", "Tool Servers": "Tool Servers", "Tool updated successfully": "orodje je uspešno posodobljeno", "Tools": "Orodja", "Tools Access": "Dostop do orodij", - "Tools are a function calling system with arbitrary code execution": "Tools are a function calling system with arbitrary code execution", + "Tools can execute arbitrary code.": "", "Tools Function Calling Prompt": "Tools Function Calling Prompt", "Tools have a function calling system that allows arbitrary code execution.": "Tools have a function calling system that allows arbitrary code execution.", "Tools Public Sharing": "Javno deljenje orodij", @@ -2327,6 +2753,8 @@ "Top": "Top", "Top K": "Top K", "Top K Reranker": "Top K Reranker", + "Top models": "", + "Total chats": "", "Transformers": "Transformers", "Trouble accessing Ollama?": "Trouble accessing Ollama?", "Trust Proxy Environment": "Trust Proxy Environment", @@ -2343,17 +2771,17 @@ "UI": "Vmesnik", "UI Scale": "Merilo vmesnika", "Unarchive All": "Odstrani vse iz arhiva", - "Unarchive All Archived Chats": "Odstrani iz arhiva All Archived pogovori", "Unarchive Chat": "Odstrani iz arhiva pogovor", + "Unassigned": "", "Underline": "Underline", + "unknown": "", "Unknown": "Neznano", "Unknown User": "Unknown User", "Unloads {{FROM_NOW}}": "Unloads {{FROM_NOW}}", - "Unlock mysteries": "Unlock mysteries", "Unmute": "Vklopi zvok", "Unpin": "Odpni", "Unpin from Sidebar": "Odpni iz stranske vrstice", - "Unravel secrets": "Unravel secrets", + "Unread": "", "Unshare All": "Prekliči deljenje All", "Unshare All Shared Chats": "Prekliči deljenje All Shared pogovori", "Unshare Chat": "Prekliči deljenje pogovor", @@ -2361,12 +2789,16 @@ "Untagged": "Untagged", "Untitled": "Untitled", "Update": "Posodobi", + "Update All Models": "", "Update and Copy Link": "Posodobi in kopiraj povezavo", "Update Email": "Posodobi e-pošta", + "Update embedding model": "", "Update for the latest features and improvements.": "Posodobi for the latest features and improvements.", + "Update model": "", "Update Name": "Posodobi ime", "Update password": "Posodobi geslo", "Update Picture": "Posodobi Picture", + "Update the password used for email and password sign-in.": "", "Update your status": "Posodobi your status", "Updated": "Updated", "Updated at": "Updated at", @@ -2374,15 +2806,20 @@ "Upgrade to a licensed plan for enhanced capabilities, including custom theming and branding, and dedicated support.": "Upgrade to a licensed plan for enhanced capabilities, including custom theming and branding, and dedicated support.", "Upload": "Naloži", "Upload a GGUF model": "Naloži a GGUF model", + "Upload a local Python pipeline file to the selected server.": "", + "Upload a workflow.json file exported as API format from ComfyUI.": "", "Upload Audio": "Naloži zvok", "Upload directory": "Mapa za nalaganje", "Upload files": "Naloži datoteke", "Upload Files": "Naloži datoteke", "Upload Model": "Naloži model", + "Upload or reset the image shown behind chat content.": "", + "Upload Photo": "", "Upload Pipeline": "Naloži cevovod", "Upload profile image": "Naloži profile image", "Upload Progress": "Napredek nalaganja", "Uploaded files or images": "Uploaded files or images", + "Uploading": "", "Uploading {{current}}/{{total}}: {{file}}": "Uploading {{current}}/{{total}}: {{file}}", "Uploading...": "Uploading...", "URL": "URL", @@ -2390,53 +2827,78 @@ "URL Mode": "URL Mode", "Usage": "Usage", "Use": "Uporabi", - "Use '#' in the prompt input to load and include your knowledge.": "Use '#' in the prompt input to load and include your knowledge.", "Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.": "Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.", + "Use a Gemini API key for image generation.": "", "Use a valid event name or pattern like user.*": "Use a valid event name or pattern like user.*", + "Use a wider chat layout on large displays.": "", + "Use an API key when your ComfyUI server requires one.": "", + "Use an LLM to improve tables, forms, math, and layout detection.": "", "Use Base64": "Use Base64", "Use Chat Completions API": "Use Chat Completions API", + "Use device vibration feedback on supported Android devices.": "", "Use discovered scopes": "Use discovered scopes", "Use groups to organize your users and assign permissions.": "Use groups to organize your users and assign permissions.", "Use LLM": "Use 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.": "Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.", + "Use proxy environment variables to fetch page contents.": "", + "Use search results without fetching page contents.": "", + "Use segmented retrieval for focused and relevant content extraction.": "", + "Use segmented retrieval for focused and relevant context.": "", + "Use segmented retrieval for focused context.": "", + "Use styled formatting when exporting chats to PDF.": "", + "Use the active chat title as the browser tab title.": "", + "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", + "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "Use Web Search?", "user": "user", "User": "Uporabnik", "User Access": "User Access", "User Activity": "User Activity", + "User Connections": "", "User Groups": "Skupine uporabnikov", "User location successfully retrieved.": "Lokacija uporabnika je uspešno pridobljena.", "User menu": "User menu", + "User messages": "", "User Preview": "User Preview", "User ratings (thumbs up/down)": "User ratings (thumbs up/down)", "User Status": "User Status", + "User Variables": "", "User Webhooks": "User Webhooks", "Username": "Uporabniško ime", "Username Claim": "Username Claim", "users": "users", "Users": "Uporabniki", "Uses DefaultAzureCredential to authenticate": "Uses DefaultAzureCredential to authenticate", + "Uses defaults": "", "Uses OAuth 2.1 Dynamic Client Registration": "Uses OAuth 2.1 Dynamic Client Registration", "Using Entire Document": "Using Entire Document", "Using Focused Retrieval": "Using Focused Retrieval", "Using the default arena model with all models. Click the plus button to add custom models.": "Using the default arena model with all models. Click the plus button to add custom models.", - "Valid time units:": "Valid time units:", - "Validate certificate": "Validate certificate", + "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", + "Validate Certificate": "", + "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Valves updated", "Valves updated successfully": "Valves je uspešno posodobljeno", "variable": "variable", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "Vector Field", "Verify Connection": "Verify Connection", "Verify SSL Certificate": "Verify SSL Certificate", + "Verify the LDAP server certificate when TLS is enabled.": "", "Version": "Različica", "Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} of {{totalVersions}}", "Version deleted": "Version deleted", + "View chat": "", "View Replies": "View Replies", - "View Result from **{{NAME}}**": "View Result from **{{NAME}}**", + "View Result from {{NAME}}": "", "View source: {{name}}": "View source: {{name}}", "View source: {{title}}": "View source: {{title}}", + "View the installed version and check release updates.": "", "Visibility": "Visibility", "Visible": "Visible", "Visible to all users": "Visible to all users", @@ -2446,6 +2908,8 @@ "Voice Input": "Glasovni vnos", "Voice mode": "Voice mode", "Voice Mode Prompt": "Voice Mode Prompt", + "Wait for the current response to finish before compacting.": "", + "Wait for the current response to finish before forking.": "", "Waiting for upload...": "Waiting for upload...", "Warning": "Opozorilo", "Warning:": "Warning:", @@ -2462,6 +2926,7 @@ "Web Search Engine": "Pogon spletnega iskanja", "Web Search in Chat": "Web Search in Chat", "Web Search Query Generation": "Web Search Query Generation", + "Webhook": "", "Webhook deleted": "Webhook deleted", "Webhook Name": "Webhook Name", "Webhook saved": "Webhook saved", @@ -2473,7 +2938,10 @@ "WebUI will make requests to \"{{url}}/api/chat\"": "WebUI will make requests to \"{{url}}/api/chat\"", "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI will make requests to \"{{url}}/chat/completions\"", "Week": "Teden", + "Week of": "", "Weekly": "Tedensko", + "Weekly at": "", + "Welcome to your AI home.": "", "What are you trying to achieve?": "What are you trying to achieve?", "What are you working on?": "What are you working on?", "What is NOT shared:": "What is NOT shared:", @@ -2481,14 +2949,14 @@ "What's New in": "What's New in", "What's on your mind?": "What's on your mind?", "When": "When", + "When disabled, keyboard shortcuts will not trigger any actions.": "", "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 (Local)", "Who can share to this group": "Who can share to this group", "Why?": "Why?", "Widescreen Mode": "Widescreen Mode", "Width": "Width", + "Width in pixels to compress images to. Leave empty for no compression.": "", "Wikipedia": "Wikipedia", "Won": "Won", "Working Directory": "Working Directory", @@ -2509,8 +2977,8 @@ "Yandex Web Search URL": "Yandex Web Search URL", "Yearly": "Yearly", "Yesterday": "Včeraj", - "Yesterday at {{LOCALIZED_TIME}}": "Yesterday at {{LOCALIZED_TIME}}", "You": "Vi", + "You are a sub-agent...": "", "You are currently using a trial license. Please contact support to upgrade your license.": "You are currently using a trial license. Please contact support to upgrade your license.", "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "You can only chat with a maximum of {{maxCount}} file(s) at a time.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.", @@ -2525,13 +2993,13 @@ "You do not have permission to upload files to this knowledge base.": "You do not have permission to upload files to this knowledge base.", "You do not have permission to upload files.": "You do not have permission to upload files.", "You do not have permission to upload web content.": "You do not have permission to upload web content.", + "You have more than 50 users, which often means this workspace is supporting organizational use. Open WebUI is free to use as-is, with no restrictions or hidden limits, and we want to keep it that way.": "", "You have no archived conversations.": "Nimate arhiviranih pogovorov.", "You have no shared conversations.": "You have no shared conversations.", "You have shared this chat": "You have shared this chat", "You.com API Key": "You.com API Key", "You're a helpful assistant.": "You're a helpful assistant.", "You're now logged in.": "You're now logged in.", - "Your Account": "Your Account", "Your account status is currently pending activation.": "Vaš račun trenutno čaka na aktivacijo.", "Your browser does not support the audio tag.": "Vaš brskalnik ne podpira zvočne oznake.", "Your browser does not support the video tag.": "Vaš brskalnik ne podpira video oznake.", diff --git a/src/lib/i18n/locales/sr-RS/translation.json b/src/lib/i18n/locales/sr-RS/translation.json index ef7c195e8f..95212fd7a3 100644 --- a/src/lib/i18n/locales/sr-RS/translation.json +++ b/src/lib/i18n/locales/sr-RS/translation.json @@ -124,6 +124,7 @@ "Add to favorites": "", "Add User": "Додај корисника", "Add User Group": "Додај корисничку групу", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -197,6 +198,7 @@ "Allow User Location": "Дозволи корисничку локацију", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -230,6 +232,7 @@ "and create a new shared link.": "и направи нову дељену везу.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Основна адреса API-ја", "API Key": "API кључ", @@ -295,6 +298,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -437,8 +441,11 @@ "Chat Permissions": "Дозволе ћаскања", "Chat Tags Auto-Generation": "Самостварање ознака ћаскања", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Ћаскања", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Провери поново", "Check for updates": "Потражи ажурирања", @@ -446,6 +453,7 @@ "Choose a model before saving...": "Изабери модел пре чувања...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -479,6 +487,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Очисти сећања", "Clear Memory": "", @@ -571,6 +580,7 @@ "Confirm": "Потврди", "Confirm Password": "Потврди лозинку", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Потврди радњу", "Confirm your new password": "Потврди нову лозинку", "Confirm Your Password": "", @@ -727,6 +737,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "Подразумевана улога корисника", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -775,6 +786,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Упутства нису праћена у потпуности", "Direct": "", @@ -846,6 +858,7 @@ "Download as SVG": "", "Download canceled": "Преузимање отказано", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -893,6 +906,7 @@ "Edit Terminal Connection": "", "Edit User": "Измени корисника", "Edit User Group": "Измени корисничку групу", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -926,6 +940,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Омогућено", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1185,6 +1200,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Неуспешно чување разговора", "Failed to save models configuration": "", @@ -1252,6 +1268,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1299,6 +1316,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1477,6 +1495,7 @@ "Keep in Sidebar": "", "Key": "Кључ", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Знање", "Knowledge Access": "Приступ знању", @@ -1550,9 +1569,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Слушам...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "ВЈМ-ови (LLM-ови) могу правити грешке. Проверите важне податке.", "Loaded": "", "Loader": "", @@ -1591,6 +1610,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Март", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1663,7 +1684,6 @@ "Model": "Модел", "Model '{{modelName}}' has been successfully downloaded.": "Модел „{{modelName}}“ је успешно преузет.", "Model '{{modelTag}}' is already in queue for downloading.": "Модел „{{modelTag}}“ је већ у реду за преузимање.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Модел {{моделНаме}} није способан за вид", "Model {{name}} is now {{status}}": "Модел {{наме}} је сада {{статус}}", @@ -1762,8 +1782,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1794,6 +1817,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1835,6 +1859,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Нема корисника.", "No valves": "", "No valves to update": "", @@ -1906,6 +1931,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Упс! Користите неподржани метод (само фронтенд). Молимо вас да покренете WebUI са бекенда.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1983,6 +2009,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Приступ медијским уређајима одбијен", "Permission denied when accessing microphone": "Приступ микрофону је одбијен", @@ -2046,6 +2073,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2053,7 +2081,10 @@ "Previous 30 days": "Претходних 30 дана", "Previous 7 days": "Претходних 7 дана", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2189,6 +2220,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2197,6 +2229,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Исход", "RESULT": "Исход", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2242,6 +2275,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Претражи", @@ -2258,6 +2292,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Претражи филтере", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2343,6 +2378,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Изабрани модели не подржавају уносе слика", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Пошаљи", "Send a Message": "Пошаљи поруку", @@ -2463,6 +2499,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2499,6 +2536,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Заустави", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Секвенца заустављања", @@ -2530,6 +2568,7 @@ "Support": "Подршка", "Support this plugin:": "Подржите овај прикључак", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2728,6 +2767,7 @@ "Unmute": "", "Unpin": "Откачи", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2735,6 +2775,7 @@ "Untagged": "Неозначено", "Untitled": "", "Update": "Ажурирај", + "Update All Models": "", "Update and Copy Link": "Ажурирај и копирај везу", "Update Email": "", "Update embedding model": "", @@ -2792,6 +2833,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "корисник", @@ -2806,6 +2848,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Корисничко име", "Username Claim": "", @@ -2820,10 +2863,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Вентили", "Valves updated": "Вентили ажурирани", "Valves updated successfully": "Вентили успешно ажурирани", "variable": "променљива", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/sv-SE/translation.json b/src/lib/i18n/locales/sv-SE/translation.json index 4f65dd6380..4e8e68b235 100644 --- a/src/lib/i18n/locales/sv-SE/translation.json +++ b/src/lib/i18n/locales/sv-SE/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Lägg till bland favoriter", "Add User": "Lägg till användare", "Add User Group": "Lägg till användargrupp", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Lägg till webbsida", "Add your Open Terminal URL and API key in Settings → Integrations.": "Lägg till din Open Terminal-URL och API-nyckel i Inställningar → Integrationer.", @@ -190,6 +191,7 @@ "Allow User Location": "Tillåt användarplats", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "och skapa en ny delad länk.", "Android": "Android", "Anyone": "Vem som helst", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API-bas-URL", "API Key": "API-nyckel", @@ -288,6 +291,7 @@ "At time of event": "Vid händelsens tidpunkt", "Attach File From Knowledge": "Bifoga fil från kunskap", "Attach Files": "Bifoga filer", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Bifoga kunskap", "Attach Notes": "Bifoga anteckningar", "Attach Webpage": "Bifoga webbsida", @@ -430,8 +434,11 @@ "Chat Permissions": "Chattbehörigheter", "Chat Tags Auto-Generation": "Automatisk generering av chatt-taggar", "Chat unshared successfully.": "Chatta odelat framgångsrikt.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "chattar", "Chats": "Chattar", + "Chats Open Sharing": "", "Chats Public Sharing": "Offentlig delning av chattar", "Check Again": "Kontrollera igen", "Check for updates": "Sök efter uppdateringar", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Välj en modell innan du sparar...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Rensa minnet", "Clear Memory": "Rensa minnet", @@ -563,6 +572,7 @@ "Confirm": "Bekräfta", "Confirm Password": "Bekräfta lösenord", "Confirm Prompt from Embed": "Bekräfta uppmaning från inbäddning", + "Confirm recording": "", "Confirm your action": "Bekräfta din åtgärd", "Confirm your new password": "Bekräfta ditt nya lösenord", "Confirm Your Password": "Bekräfta ditt lösenord", @@ -719,6 +729,7 @@ "Default to ALL": "Standard till ALLA", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Standard till segmenterad hämtning för fokuserad och relevant innehållsextrahering, det här rekommenderas för de flesta fall.", + "Default Upload Mode": "", "Default User Role": "Standardanvändarroll", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "Avmarkera", "Detect Artifacts Automatically": "Detektera artefakter automatiskt", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktera", "Didn't fully follow instructions": "Följde inte instruktionerna", "Direct": "Direkt", @@ -838,6 +850,7 @@ "Download as SVG": "Ladda ner som SVG", "Download canceled": "Nedladdning avbruten", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Redigera terminalanslutning", "Edit User": "Redigera användare", "Edit User Group": "Redigera användargrupp", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "Redigera innehållet i workflow.json", "edited": "redigerad", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Aktivera, inaktivera eller anpassa de taggar för resonemang som används av modellen. \"Enabled\" använder standardtaggar, \"Disabled\" stänger av resonemangstaggar och \"Custom\" låter dig ange dina egna start- och sluttaggar.", "Enabled": "Aktiverad", + "End call": "", "End Tag": "Avsluta tagg", "Endpoint": "", "Endpoint URL": "Endpoint URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Misslyckades med att ta bort medlemmen", "Failed to render diagram": "Misslyckades med att rendera diagram", "Failed to render visualization": "Misslyckades med att rendera visualisering", + "Failed to save chat variables": "", "Failed to save connections": "Misslyckades med att spara anslutningar", "Failed to save conversation": "Misslyckades med att spara konversationen", "Failed to save models configuration": "Misslyckades med att spara modellkonfiguration", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Mappen har uppdaterats", "Folders": "Mappar", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Uppföljningsfrågor", "Follow Up Generation": "Generering av uppföljningsfrågor", "Follow Up Generation Prompt": "Prompt för generering av uppföljningsfrågor", @@ -1289,6 +1306,7 @@ "Generate an image": "Generera en bild", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Generera och redigera bilder", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Generera meddelandepar", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Behåll i sidofältet", "Key": "Nyckel", "Key is required": "Nyckel krävs", + "key_name": "", "Keyboard": "", "Knowledge": "Kunskapsbaser", "Knowledge Access": "Kunskapsåtkomst", @@ -1540,9 +1559,9 @@ "List": "Lista", "List calendars, search, create, update, and delete calendar events": "Lista kalendrar, sök, skapa, uppdatera och ta bort kalenderhändelser", "Listening...": "Lyssnar...", + "LiteLLM": "", "Live": "Lev", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM:er kan göra misstag. Granska viktig information.", "Loaded": "Inläst", "Loader": "Inläsare", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "mars", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown textdelare för rubriker", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Modell", "Model '{{modelName}}' has been successfully downloaded.": "Modellen '{{modelName}}' har laddats ner.", "Model '{{modelTag}}' is already in queue for downloading.": "Modellen '{{modelTag}}' är redan i kö för nedladdning.", - "Model {{modelId}} not found": "Modell {{modelId}} hittades inte", "Model {{modelName}} deleted successfully": "Modellen {{modelName}} togs bort", "Model {{modelName}} is not vision capable": "Modellen {{modelName}} har inte stöd för vision/syn", "Model {{name}} is now {{status}}": "Modellen {{name}} är nu {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "Ny webbhook", "new-channel": "ny-kanal", "Next message": "Nästa meddelande", + "Next month": "", "Next page": "", "Next run": "Nästa körning", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Ingen tillgång beviljas. Privat för dig.", "No actions found": "", "No activity data": "Ingen aktivitetsdata", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "Inga filer i den här kunskapsbas.", "No files yet. Upload files or run Python code to create them.": "Inga filer ännu. Ladda upp filer eller kör Python-kod för att skapa dem.", "No filters found": "", + "No folders": "", "No functions found": "Inga funktioner hittades", "No groups found": "Inga grupper hittades", "No history available": "Ingen historik tillgänglig", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Inga verktyg hittades", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Inga användare hittades.", "No valves": "Inga ventiler", "No valves to update": "Inga ventiler att uppdatera", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Hoppsan! Det finns fortfarande filer som laddas upp. Vänta tills uppladdningen är klar.", "Oops! There was an error in the previous response.": "Hoppsan! Det uppstod ett fel i föregående svar.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hoppsan! Du använder en ej stödd metod (endast frontend). servera WebUI från backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Väntande användaröverlagringsinnehåll", "Pending User Overlay Title": "Väntande användaröverlagringstitel", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Nekad behörighet vid åtkomst till mediaenheter", "Permission denied when accessing microphone": "Nekad behörighet vid åtkomst till mikrofon", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix-ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix-ID används för att undvika konflikter med andra anslutningar genom att lägga till ett prefix till modell-ID:n - lämna tomt för att inaktivera", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Förhindra filskapande", "Preview": "Förhandsgranska", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Föregående 30 dagar", "Previous 7 days": "Föregående 7 dagar", "Previous message": "Föregående meddelande", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Privat", "Private conversation between selected users": "Privat konversation mellan utvalda användare", "Production version updated": "Produktionsversionen uppdaterad", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Återställ vektorlagring/kunskapsbaser", "Reset view": "Återställ vy", "Response": "Svar", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Svarsaviseringar kan inte aktiveras eftersom webbplatsens behörigheter har nekats. Besök dina webbläsarinställningar för att ge nödvändig åtkomst.", "Response Splitting": "", "Response Watermark": "Svarsvattenstämpel", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Resultat", "RESULT": "Resultat", + "Retained Messages": "", "Retrieval": "Hämtning", "Retrieval Query Generation": "Generering av hämtningsfrågor", "Retrieved {{count}} sources": "Hämtade {{count}} källor", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "Schemalagd tid måste ligga i framtiden", "Scopes": "", "Scroll On Branch Change": "Scrolla vid grenbyte", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Rulla högst upp", "Search": "Sök", @@ -2245,6 +2279,7 @@ "Search Files": "Sök filer", "Search filters": "", "Search Filters": "Sökfilter", + "Search folders": "", "search for archived chats": "sök efter arkiverade konversationer", "search for folders": "sök efter mappar", "search for pinned chats": "sök efter fästa konversationer", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "Vald modell: {{modelName}}", "Selected model(s) do not support image inputs": "Valda modeller stöder inte bildinmatningar", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantisk", "Send": "Skicka", "Send a Message": "Skicka ett meddelande", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "Färdigheter Offentlig delning", "Skills Sharing": "Delning av färdigheter", "Skip Cache": "Hoppa över cache", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Något gick fel :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Steg", "Stop": "Stopp", + "Stop camera": "", "Stop Download": "Stoppa Ladda ner", "Stop Generating": "Sluta generera", "Stop Sequence": "Stoppsekvens", @@ -2516,6 +2554,7 @@ "Support": "Stöd", "Support this plugin:": "Stöd den här plugin", "Supported MIME Types": "MIME-typer som stöds", + "Switch camera": "", "Switch to JSON editor": "Byt till JSON-redigerare", "Switch to visual editor": "Byt till visuell redigerare", "Sync": "Synkronisera", @@ -2714,6 +2753,7 @@ "Unmute": "Slå på ljud", "Unpin": "Ta bort fästning", "Unpin from Sidebar": "Lossa från sidofältet", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Chatt utan delning", @@ -2721,6 +2761,7 @@ "Untagged": "Otaggad", "Untitled": "Namnlös", "Update": "Uppdatera", + "Update All Models": "", "Update and Copy Link": "Uppdatera och kopiera länk", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "användare", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Användarnas betyg (tummen upp/ned)", "User Status": "Användarstatus", + "User Variables": "", "User Webhooks": "Användar-webhooks", "Username": "Användarnamn", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Ventiler", "Valves updated": "Ventiler uppdaterade", "Valves updated successfully": "Ventiler uppdaterade", "variable": "variabel", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Verifiera anslutning", "Verify SSL Certificate": "Verifiera SSL-certifikat", diff --git a/src/lib/i18n/locales/ta-IN/translation.json b/src/lib/i18n/locales/ta-IN/translation.json index 26f076a7bb..189a73fa67 100644 --- a/src/lib/i18n/locales/ta-IN/translation.json +++ b/src/lib/i18n/locales/ta-IN/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "பிடித்தவைகளில் சேர்க்கவும்", "Add User": "பயனரைச் சேர்க்கவும்", "Add User Group": "பயனர் குழுவைச் சேர்க்கவும்", + "Add User Variable": "", "Add webhook": "", "Add webpage": "வலைப்பக்கத்தைச் சேர்க்கவும்", "Add your Open Terminal URL and API key in Settings → Integrations.": "அமைப்புகள் → ஒருங்கிணைப்புகளில் உங்கள் Open Terminal URL மற்றும் API விசையைச் சேர்க்கவும்.", @@ -190,6 +191,7 @@ "Allow User Location": "பயனர் இருப்பிடத்தை அனுமதிக்கவும்", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "மற்றும் புதிய பகிரப்பட்ட இணைப்பை உருவாக்கவும்.", "Android": "Android", "Anyone": "யாரேனும்", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API அடிப்படை URL", "API Key": "API திறவுகோல்", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "அறிவிலிருந்து கோப்பை இணைக்கவும்", "Attach Files": "கோப்புகளை இணைக்கவும்", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "அறிவை இணைக்கவும்", "Attach Notes": "குறிப்புகளை இணைக்கவும்", "Attach Webpage": "இணையப் பக்கத்தை இணைக்கவும்", @@ -430,8 +434,11 @@ "Chat Permissions": "அரட்டை அனுமதிகள்", "Chat Tags Auto-Generation": "அரட்டை குறிச்சொற்கள் தானியங்கு உருவாக்கம்", "Chat unshared successfully.": "அரட்டை வெற்றிகரமாக பகிரப்பட்டது.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "அரட்டைகள்", "Chats": "அரட்டைகள்", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "மீண்டும் சரிபார்க்கவும்", "Check for updates": "புதுப்பிப்புகளைச் சரிபார்க்கவும்", @@ -439,6 +446,7 @@ "Choose a model before saving...": "சேமிக்கும் முன் மாதிரியைத் தேர்வு செய்யவும்...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "தெளிவான நினைவகம்", "Clear Memory": "தெளிவான நினைவகம்", @@ -563,6 +572,7 @@ "Confirm": "உறுதிப்படுத்து", "Confirm Password": "கடவுச்சொல்லை உறுதிப்படுத்துங்கள்", "Confirm Prompt from Embed": "உட்பொதிவிலிருந்து உடனடியாக உறுதிப்படுத்தவும்", + "Confirm recording": "", "Confirm your action": "உங்கள் செயலை உறுதிப்படுத்தவும்", "Confirm your new password": "உங்கள் புதிய கடவுச்சொல்லை உறுதிப்படுத்தவும்", "Confirm Your Password": "உங்கள் கடவுச்சொல்லை உறுதிப்படுத்தவும்", @@ -719,6 +729,7 @@ "Default to ALL": "ALLக்கு இயல்புநிலை", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "கவனம் செலுத்திய மற்றும் தொடர்புடைய உள்ளடக்கத்தைப் பிரித்தெடுப்பதற்காக பிரித்தெடுக்கப்பட்ட மீட்டெடுப்புக்கு இயல்புநிலை, இது பெரும்பாலான சந்தர்ப்பங்களில் பரிந்துரைக்கப்படுகிறது.", + "Default Upload Mode": "", "Default User Role": "இயல்புநிலை பயனர் பங்கு", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "தேர்வுநீக்கு", "Detect Artifacts Automatically": "கலைப்பொருட்களை தானாக கண்டறியவும்", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "ஆணையிடுங்கள்", "Didn't fully follow instructions": "வழிமுறைகளை முழுமையாகப் பின்பற்றவில்லை", "Direct": "நேரடி", @@ -838,6 +850,7 @@ "Download as SVG": "SVG ஆகப் பதிவிறக்கு", "Download canceled": "பதிவிறக்கம் ரத்து செய்யப்பட்டது", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "டெர்மினல் இணைப்பைத் திருத்து", "Edit User": "பயனரைத் திருத்து", "Edit User Group": "பயனர் குழுவைத் திருத்தவும்", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "workflow.json உள்ளடக்கத்தைத் திருத்தவும்", "edited": "திருத்தப்பட்டது", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "மாதிரியால் பயன்படுத்தப்படும் பகுத்தறிவு குறிச்சொற்களை இயக்கவும், முடக்கவும் அல்லது தனிப்பயனாக்கவும். \"இயக்கப்பட்டது\" இயல்புநிலை குறிச்சொற்களைப் பயன்படுத்துகிறது, \"முடக்கப்பட்டது\" பகுத்தறிவு குறிச்சொற்களை முடக்குகிறது, மேலும் \"தனிப்பயன்\" உங்கள் சொந்த தொடக்க மற்றும் முடிவு குறிச்சொற்களைக் குறிப்பிட உங்களை அனுமதிக்கிறது.", "Enabled": "இயக்கப்பட்டது", + "End call": "", "End Tag": "எண்ட் டேக்", "Endpoint": "", "Endpoint URL": "இறுதிப்புள்ளி URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "உறுப்பினரை அகற்ற முடியவில்லை", "Failed to render diagram": "வரைபடத்தை வழங்குவதில் தோல்வி", "Failed to render visualization": "காட்சிப்படுத்தலை வழங்குவதில் தோல்வி", + "Failed to save chat variables": "", "Failed to save connections": "இணைப்புகளைச் சேமிப்பதில் தோல்வி", "Failed to save conversation": "உரையாடலைச் சேமிக்க முடியவில்லை", "Failed to save models configuration": "மாதிரிகள் உள்ளமைவைச் சேமிப்பதில் தோல்வி", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "கோப்புறை வெற்றிகரமாக புதுப்பிக்கப்பட்டது", "Folders": "கோப்புறைகள்", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "பின்தொடரவும்", "Follow Up Generation": "ஃபாலோ அப் தலைமுறை", "Follow Up Generation Prompt": "ஃபாலோ அப் ஜெனரேஷன் ப்ராம்ப்ட்", @@ -1289,6 +1306,7 @@ "Generate an image": "ஒரு படத்தை உருவாக்கவும்", "Generate an image prompt before sending the request.": "", "Generate and edit images": "படங்களை உருவாக்கி திருத்தவும்", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "செய்தி ஜோடியை உருவாக்கவும்", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "பக்கப்பட்டியில் வைக்கவும்", "Key": "முக்கிய", "Key is required": "சாவி தேவை", + "key_name": "", "Keyboard": "", "Knowledge": "அறிவு", "Knowledge Access": "அறிவு அணுகல்", @@ -1540,9 +1559,9 @@ "List": "பட்டியல்", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "கேட்கிறது...", + "LiteLLM": "", "Live": "வாழ்க", "llama.cpp": "", - "Llama.cpp": "லாமா.சிபிபி", "LLMs can make mistakes. Verify important information.": "எல்எல்எம்கள் தவறு செய்யலாம். முக்கியமான தகவலை சரிபார்க்கவும்.", "Loaded": "", "Loader": "ஏற்றி", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "மார்ச்", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "மார்க் டவுன்", "Markdown Header Text Splitter": "மார்க் டவுன் தலைப்பு உரை பிரிப்பான்", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "மாதிரி", "Model '{{modelName}}' has been successfully downloaded.": "மாடல் '{{modelName}}' வெற்றிகரமாகப் பதிவிறக்கப்பட்டது.", "Model '{{modelTag}}' is already in queue for downloading.": "மாடல் '{{modelTag}}' ஏற்கனவே பதிவிறக்குவதற்கு வரிசையில் உள்ளது.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "மாதிரி {{modelName}} வெற்றிகரமாக நீக்கப்பட்டது", "Model {{modelName}} is not vision capable": "மாதிரி {{modelName}} பார்வை திறன் இல்லை", "Model {{name}} is now {{status}}": "மாடல் {{name}} இப்போது {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "புதிய Webhook", "new-channel": "புதிய சேனல்", "Next message": "அடுத்த செய்தி", + "Next month": "", "Next page": "", "Next run": "அடுத்த இயக்கம்", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "அணுகல் மானியங்கள் இல்லை. உங்களுக்கு தனிப்பட்டது.", "No actions found": "", "No activity data": "செயல்பாட்டுத் தரவு இல்லை", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "இந்த அறிவுத் தளத்தில் கோப்புகள் இல்லை.", "No files yet. Upload files or run Python code to create them.": "இதுவரை கோப்புகள் இல்லை. கோப்புகளைப் பதிவேற்றவும் அல்லது அவற்றை உருவாக்க பைதான் குறியீட்டை இயக்கவும்.", "No filters found": "", + "No folders": "", "No functions found": "செயல்பாடுகள் எதுவும் இல்லை", "No groups found": "குழுக்கள் எதுவும் இல்லை", "No history available": "வரலாறு இல்லை", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "கருவிகள் எதுவும் கிடைக்கவில்லை", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "பயனர்கள் யாரும் காணப்படவில்லை.", "No valves": "வால்வுகள் இல்லை", "No valves to update": "புதுப்பிக்க வால்வுகள் இல்லை", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "அச்சச்சோ! கோப்புகள் இன்னும் பதிவேற்றப்படுகின்றன. பதிவேற்றம் முடிவடையும் வரை காத்திருக்கவும்.", "Oops! There was an error in the previous response.": "அச்சச்சோ! முந்தைய பதிலில் பிழை இருந்தது.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "அச்சச்சோ! நீங்கள் ஆதரிக்கப்படாத முறையைப் பயன்படுத்துகிறீர்கள் (முன்புறம் மட்டும்). பின்தளத்தில் இருந்து WebUI ஐ வழங்கவும்.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "நிலுவையில் உள்ள பயனர் மேலடுக்கு உள்ளடக்கம்", "Pending User Overlay Title": "நிலுவையில் உள்ள பயனர் மேலடுக்கு தலைப்பு", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "மீடியா சாதனங்களை அணுகும்போது அனுமதி மறுக்கப்பட்டது", "Permission denied when accessing microphone": "மைக்ரோஃபோனை அணுகும்போது அனுமதி மறுக்கப்பட்டது", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "முன்னொட்டு ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "மாதிரி ஐடிகளில் முன்னொட்டைச் சேர்ப்பதன் மூலம் பிற இணைப்புகளுடன் முரண்பாடுகளைத் தவிர்க்க ID முன்னொட்டு பயன்படுத்தப்படுகிறது - முடக்குவதற்கு காலியாக விடவும்", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "கோப்பு உருவாக்கத்தைத் தடுக்கவும்", "Preview": "முன்னோட்டம்", @@ -2043,7 +2071,10 @@ "Previous 30 days": "முந்தைய 30 நாட்கள்", "Previous 7 days": "முந்தைய 7 நாட்கள்", "Previous message": "முந்தைய செய்தி", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "தனியார்", "Private conversation between selected users": "தேர்ந்தெடுக்கப்பட்ட பயனர்களிடையே தனிப்பட்ட உரையாடல்", "Production version updated": "தயாரிப்பு பதிப்பு புதுப்பிக்கப்பட்டது", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "வெக்டர் சேமிப்பகம்/அறிவை மீட்டமைக்கவும்", "Reset view": "பார்வையை மீட்டமைக்கவும்", "Response": "பதில்", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "இணையதள அனுமதிகள் மறுக்கப்பட்டுள்ளதால், பதில் அறிவிப்புகளை செயல்படுத்த முடியாது. தேவையான அணுகலை வழங்க உங்கள் உலாவி அமைப்புகளைப் பார்வையிடவும்.", "Response Splitting": "", "Response Watermark": "பதில் வாட்டர்மார்க்", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "முடிவு", "RESULT": "முடிவு", + "Retained Messages": "", "Retrieval": "மீட்டெடுப்பு", "Retrieval Query Generation": "மீட்டெடுப்பு வினவல் உருவாக்கம்", "Retrieved {{count}} sources": "மீட்டெடுக்கப்பட்டது {{count}} ஆதாரங்கள்", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "திட்டமிட்ட நேரம் எதிர்காலத்தில் இருக்க வேண்டும்", "Scopes": "", "Scroll On Branch Change": "கிளை மாற்றத்தில் உருட்டவும்", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "தேடு", @@ -2245,6 +2279,7 @@ "Search Files": "கோப்புகளைத் தேடுங்கள்", "Search filters": "", "Search Filters": "தேடல் வடிப்பான்கள்", + "Search folders": "", "search for archived chats": "காப்பகப்படுத்தப்பட்ட அரட்டைகளைத் தேடுங்கள்", "search for folders": "கோப்புறைகளைத் தேடுங்கள்", "search for pinned chats": "பின் செய்யப்பட்ட அரட்டைகளைத் தேடுங்கள்", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "தேர்ந்தெடுக்கப்பட்ட மாதிரி: {{modelName}}", "Selected model(s) do not support image inputs": "தேர்ந்தெடுக்கப்பட்ட மாதிரி(கள்) பட உள்ளீடுகளை ஆதரிக்காது", + "Selected models define incompatible Chat Variables.": "", "semantic": "சொற்பொருள்", "Send": "அனுப்பு", "Send a Message": "ஒரு செய்தியை அனுப்பு", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "திறன்கள் பொது பகிர்வு", "Skills Sharing": "திறன் பகிர்வு", "Skip Cache": "தற்காலிக சேமிப்பைத் தவிர்க்கவும்", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "ஏதோ தவறாகிவிட்டது :/", "Sonar": "சோனார்", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "படிகள்", "Stop": "நிறுத்து", + "Stop camera": "", "Stop Download": "பதிவிறக்கத்தை நிறுத்து", "Stop Generating": "உருவாக்குவதை நிறுத்து", "Stop Sequence": "நிறுத்து வரிசை", @@ -2516,6 +2554,7 @@ "Support": "ஆதரவு", "Support this plugin:": "இந்த செருகுநிரலை ஆதரிக்கவும்:", "Supported MIME Types": "ஆதரிக்கப்படும் MIME வகைகள்", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "ஒத்திசை", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "அன்பின்", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "அரட்டையைப் பகிர்வதை நீக்கு", @@ -2721,6 +2761,7 @@ "Untagged": "குறியிடப்படாதது", "Untitled": "பெயரிடப்படாதது", "Update": "புதுப்பி", + "Update All Models": "", "Update and Copy Link": "இணைப்பைப் புதுப்பித்து நகலெடுக்கவும்", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "பயனர்", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "பயனர் மதிப்பீடுகள் (பெருவிரல் மேல்/கீழ்)", "User Status": "பயனர் நிலை", + "User Variables": "", "User Webhooks": "பயனர் வெப்ஹூக்குகள்", "Username": "பயனர் பெயர்", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "வால்வுகள்", "Valves updated": "வால்வுகள் புதுப்பிக்கப்பட்டன", "Valves updated successfully": "வால்வுகள் வெற்றிகரமாக புதுப்பிக்கப்பட்டன", "variable": "மாறி", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "இணைப்பைச் சரிபார்க்கவும்", "Verify SSL Certificate": "SSL சான்றிதழைச் சரிபார்க்கவும்", diff --git a/src/lib/i18n/locales/th-TH/translation.json b/src/lib/i18n/locales/th-TH/translation.json index dbfb2f2441..3ec8edf354 100644 --- a/src/lib/i18n/locales/th-TH/translation.json +++ b/src/lib/i18n/locales/th-TH/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "เพิ่มไปยังรายการโปรด", "Add User": "เพิ่มผู้ใช้", "Add User Group": "เพิ่มกลุ่มผู้ใช้", + "Add User Variable": "", "Add webhook": "เพิ่ม webhook", "Add webpage": "เพิ่ม web page", "Add your Open Terminal URL and API key in Settings → Integrations.": "เพิ่มURLและAPI keyของOpen TerminalของคุณในSettings → Integrations", @@ -183,6 +184,7 @@ "Allow User Location": "อนุญาตให้เข้าถึงตำแหน่งที่อยู่ของผู้ใช้", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "และสร้างลิงก์ที่แชร์ใหม่", "Android": "Android", "Anyone": "ใครก็ได้", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL พื้นฐานของ API", "API Key": "คีย์ API", @@ -281,6 +284,7 @@ "At time of event": "ณ เวลาของevent", "Attach File From Knowledge": "แนบไฟล์จากฐานความรู้", "Attach Files": "แนบไฟล์", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "แนบฐานความรู้", "Attach Notes": "แนบบันทึก", "Attach Webpage": "แนบหน้าเว็บ", @@ -423,8 +427,11 @@ "Chat Permissions": "สิทธิ์การแชท", "Chat Tags Auto-Generation": "การสร้างแท็กแชทอัตโนมัติ", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "แชท", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "ตรวจสอบอีกครั้ง", "Check for updates": "ตรวจสอบการอัปเดต", @@ -432,6 +439,7 @@ "Choose a model before saving...": "เลือกโมเดลก่อนบันทึก...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "ล้างความจำ", "Clear Memory": "ล้างความจำ", @@ -555,6 +564,7 @@ "Confirm": "ยืนยัน", "Confirm Password": "ยืนยันรหัสผ่าน", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "ยืนยันการดำเนินการของคุณ", "Confirm your new password": "ยืนยันรหัสผ่านใหม่ของคุณ", "Confirm Your Password": "ยืนยันรหัสผ่านของคุณ", @@ -711,6 +721,7 @@ "Default to ALL": "ค่าเริ่มต้นเป็นทั้งหมด", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "กำหนดค่าเริ่มต้นให้ใช้การดึงข้อมูลแบบแบ่งส่วนเพื่อการดึงเนื้อหาที่มีโฟกัสและเกี่ยวข้อง แนะนำให้ใช้ตัวเลือกนี้ในกรณีส่วนใหญ่", + "Default Upload Mode": "", "Default User Role": "บทบาทผู้ใช้เริ่มต้น", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "", "Detect Artifacts Automatically": "ตรวจจับ Artifacts โดยอัตโนมัติ", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "การเขียนตามคำบอก", "Didn't fully follow instructions": "ไม่ได้ทำตามคำแนะนำทั้งหมด", "Direct": "โดยตรง", @@ -830,6 +842,7 @@ "Download as SVG": "ดาวน์โหลดเป็น SVG", "Download canceled": "ยกเลิกการดาวน์โหลด", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "", "Edit User": "แก้ไขผู้ใช้", "Edit User Group": "แก้ไขกลุ่มผู้ใช้", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "แก้ไขเนื้อหา workflow.json", "edited": "แก้ไขแล้ว", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "เปิดใช้งาน ปิดใช้งาน หรือปรับแต่ง Reasoning Tag ที่โมเดลใช้ได้ \"เปิดใช้งาน\" จะใช้แท็กเริ่มต้น \"ปิดใช้งาน\" จะปิด Reasoning Tag และ \"กำหนดเอง\" จะให้คุณระบุแท็กเริ่มต้นและสิ้นสุดของคุณเอง", "Enabled": "เปิดใช้งาน", + "End call": "", "End Tag": "แท็กปิด", "Endpoint": "", "Endpoint URL": "Endpoint URL", @@ -1165,6 +1180,7 @@ "Failed to remove member": "", "Failed to render diagram": "ไม่สามารถเรนเดอร์ไดอะแกรมได้", "Failed to render visualization": "ไม่สามารถเรนเดอร์ภาพข้อมูลได้", + "Failed to save chat variables": "", "Failed to save connections": "บันทึกการเชื่อมต่อล้มเหลว", "Failed to save conversation": "บันทึกการสนทนาล้มเหลว", "Failed to save models configuration": "บันทึกการตั้งค่าโมเดลล้มเหลว", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "อัปเดตโฟลเดอร์สำเร็จแล้ว", "Folders": "โฟลเดอร์", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "ติดตามต่อ", "Follow Up Generation": "การสร้างคำถามติดตาม", "Follow Up Generation Prompt": "พรอมต์สร้างคำถามติดตามผล", @@ -1279,6 +1296,7 @@ "Generate an image": "สร้างรูปภาพ", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "สร้างคู่ข้อความ", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "ปักหมุดไว้ที่แถบด้านข้าง", "Key": "คีย์", "Key is required": "ต้องระบุคีย์", + "key_name": "", "Keyboard": "", "Knowledge": "ความรู้", "Knowledge Access": "การเข้าถึงความรู้", @@ -1530,9 +1549,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "กำลังฟัง...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM อาจทำผิดพลาดได้ โปรดตรวจสอบข้อมูลสำคัญ", "Loaded": "", "Loader": "ตัวโหลด", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "มีนาคม", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "โมเดล", "Model '{{modelName}}' has been successfully downloaded.": "โมเดล '{{modelName}}' ถูกดาวน์โหลดเรียบร้อยแล้ว", "Model '{{modelTag}}' is already in queue for downloading.": "โมเดล '{{modelTag}}' อยู่ในคิวสำหรับการดาวน์โหลดแล้ว", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "โมเดล {{modelName}} ไม่รองรับฟีเจอร์ Vision", "Model {{name}} is now {{status}}": "โมเดล {{name}} ขณะนี้ {{status}}", @@ -1742,8 +1762,11 @@ "New Webhook": "", "new-channel": "ช่องใหม่", "Next message": "ข้อความถัดไป", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "ไม่พบฟังก์ชัน", "No groups found": "", "No history available": "", @@ -1815,6 +1839,7 @@ "No tools accessible": "", "No tools found": "ไม่พบเครื่องมือ", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "ไม่พบผู้ใช้", "No valves": "ไม่มีวาล์ว", "No valves to update": "ไม่มีวาล์วให้อัปเดต", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "โอ๊ะ! ยังมีไฟล์กำลังอัปโหลดอยู่ กรุณารอจนกว่าอัปโหลดจะเสร็จสมบูรณ์", "Oops! There was an error in the previous response.": "ขออภัย! เกิดข้อผิดพลาดในคำตอบก่อนหน้า", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "ขออภัย! คุณกำลังใช้วิธีที่ไม่รองรับ (เฉพาะ Frontend) กรุณาให้บริการ WebUI จากฝั่ง Backend", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "เนื้อหาซ้อนทับผู้ใช้ที่รอดำเนินการ", "Pending User Overlay Title": "ชื่อหน้าซ้อนผู้ใช้ที่รอดำเนินการ", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "ไม่ได้รับอนุญาตให้เข้าถึงอุปกรณ์สื่อ", "Permission denied when accessing microphone": "ถูกปฏิเสธสิทธิ์ในการเข้าถึงไมโครโฟน", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "รหัสคำนำหน้า", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID ใช้เพื่อหลีกเลี่ยงความขัดแย้งกับการเชื่อมต่ออื่น โดยการเพิ่มคำนำหน้าให้กับ ID ของโมเดล หากต้องการปิดให้เว้นว่างไว้", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "ป้องกันการสร้างไฟล์", "Preview": "ดูตัวอย่าง", @@ -2033,7 +2061,10 @@ "Previous 30 days": "30 วันที่ผ่านมา", "Previous 7 days": "7 วันที่ผ่านมา", "Previous message": "ข้อความก่อนหน้า", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "ส่วนตัว", "Private conversation between selected users": "", "Production version updated": "", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "รีเซ็ตที่เก็บเวกเตอร์/ฐานความรู้", "Reset view": "รีเซ็ตมุมมอง", "Response": "การตอบกลับ", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "ไม่สามารถเปิดใช้งานการแจ้งเตือนการตอบกลับได้ เนื่องจากสิทธิ์ของเว็บไซต์ถูกปฏิเสธ กรุณาไปที่การตั้งค่าเบราว์เซอร์ของคุณเพื่อให้สิทธิ์การเข้าถึงที่จำเป็น", "Response Splitting": "", "Response Watermark": "ลายน้ำของคำตอบ", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "ผลลัพธ์", "RESULT": "ผลลัพธ์", + "Retained Messages": "", "Retrieval": "การดึงข้อมูล", "Retrieval Query Generation": "การสร้างคำค้นสำหรับการดึงข้อมูล", "Retrieved {{count}} sources": "ดึงข้อมูลจาก {{count}} แหล่งข้อมูลแล้ว", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "เลื่อนเมื่อเปลี่ยนสาขา", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "ค้นหา", @@ -2232,6 +2266,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "ตัวกรองการค้นหา", + "Search folders": "", "search for archived chats": "ค้นหาการแชทที่เก็บถาวร", "search for folders": "ค้นหาโฟลเดอร์", "search for pinned chats": "ค้นหาแชทที่ปักหมุด", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "โมเดลที่เลือกไม่รองรับการป้อนภาพ", + "Selected models define incompatible Chat Variables.": "", "semantic": "Semantic", "Send": "ส่ง", "Send a Message": "ส่งข้อความ", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "ข้ามแคช", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "มีบางอย่างผิดพลาด :/", "Sonar": "Sonar", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "ขั้นตอน", "Stop": "หยุด", + "Stop camera": "", "Stop Download": "", "Stop Generating": "หยุดการสร้าง", "Stop Sequence": "ลำดับการหยุด", @@ -2502,6 +2540,7 @@ "Support": "สนับสนุน", "Support this plugin:": "สนับสนุนปลั๊กอินนี้:", "Supported MIME Types": "ชนิด MIME ที่รองรับ", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2700,6 +2739,7 @@ "Unmute": "", "Unpin": "ยกเลิกการปักหมุด", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2707,6 +2747,7 @@ "Untagged": "ไม่มีแท็ก", "Untitled": "ไม่มีชื่อ", "Update": "อัปเดต", + "Update All Models": "", "Update and Copy Link": "อัปเดตและคัดลอกลิงก์", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "ผู้ใช้", @@ -2778,6 +2820,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Webhooks ของผู้ใช้", "Username": "ชื่อผู้ใช้", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "วาล์ว", "Valves updated": "วาล์วถูกอัปเดตแล้ว", "Valves updated successfully": "อัปเดตวาล์วเรียบร้อยแล้ว", "variable": "ตัวแปร", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "ตรวจสอบการเชื่อมต่อ", "Verify SSL Certificate": "ตรวจสอบใบรับรอง SSL", diff --git a/src/lib/i18n/locales/tk-TM/translation.json b/src/lib/i18n/locales/tk-TM/translation.json index 361326e94d..f876d3e3a4 100644 --- a/src/lib/i18n/locales/tk-TM/translation.json +++ b/src/lib/i18n/locales/tk-TM/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Ulanyjy goş", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "we täze paýlaşylan baglanyşyk dörediň.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Esasy URL", "API Key": "API Açar", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Çatlar", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Ýene Barla", "Check for updates": "Täzelenmeleri barla", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Saklamazdan ozal model saýlaň...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "", "Confirm Password": "Paroly Tassyklap", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Işjeň", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Söhbeti ýazdyrmak başa barmady", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Açar", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mart", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "", "Model '{{modelTag}}' is already in queue for downloading.": "", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "", "Model {{name}} is now {{status}}": "", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "", "Oops! There was an error in the previous response.": "", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "", "Permission denied when accessing microphone": "", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Öň-üşürgi", @@ -2043,7 +2071,10 @@ "Previous 30 days": "", "Previous 7 days": "", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "", "RESULT": "NETIJE", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Gözleg", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Iber", "Send a Message": "", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Bes et", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "", @@ -2516,6 +2554,7 @@ "Support": "Goldaw", "Support this plugin:": "", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "", "Untitled": "", "Update": "Täzeläň", + "Update All Models": "", "Update and Copy Link": "", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "Ulanyjy Ady", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "", "Valves updated": "", "Valves updated successfully": "", "variable": "", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index 1d6ef6f014..09d14ba385 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "Favorilere ekle", "Add User": "Kullanıcı Ekle", "Add User Group": "Kullanıcı Grubu Ekle", + "Add User Variable": "", "Add webhook": "", "Add webpage": "Web sayfası ekle", "Add your Open Terminal URL and API key in Settings → Integrations.": "Open Terminal URL'nizi ve API anahtarınızı Ayarlar → Entegrasyonlar bölümünde girin.", @@ -190,6 +191,7 @@ "Allow User Location": "Kullanıcı Konumuna İzin Ver", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "ve yeni bir paylaşılan bağlantı oluşturun.", "Android": "Android", "Anyone": "Herkes", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API Temel URL", "API Key": "API Anahtarı", @@ -288,6 +291,7 @@ "At time of event": "Etkinlik zamanında", "Attach File From Knowledge": "Bilgi Tabanından Dosya Ekle", "Attach Files": "Dosya Ekle", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "Bilgi Tabanı Ekle", "Attach Notes": "Not Ekle", "Attach Webpage": "Web sayfası ekle", @@ -430,8 +434,11 @@ "Chat Permissions": "Sohbet İzinleri", "Chat Tags Auto-Generation": "Sohbet Etiketleri Otomatik Oluşturma", "Chat unshared successfully.": "Sohbet paylaşımı başarıyla kaldırıldı.", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "sohbetler", "Chats": "Sohbetler", + "Chats Open Sharing": "", "Chats Public Sharing": "Sohbetlerin Herkese Açık Paylaşımı", "Check Again": "Tekrar Kontrol Et", "Check for updates": "Güncellemeleri kontrol et", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Kaydetmeden önce bir model seçin...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Belleği temizle", "Clear Memory": "Belleği Temizle", @@ -563,6 +572,7 @@ "Confirm": "Onayla", "Confirm Password": "Parolayı Onayla", "Confirm Prompt from Embed": "Gömülü İstemi Onayla", + "Confirm recording": "", "Confirm your action": "İşleminizi onaylayın", "Confirm your new password": "Yeni parolanızı onaylayın", "Confirm Your Password": "Parolanızı Onaylayın", @@ -719,6 +729,7 @@ "Default to ALL": "TÜMÜ'nü varsayılan olarak", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Odaklanmış ve ilgili içerik çıkarımı için varsayılan olarak bölümlenmiş alma kullanılır, çoğu durum için bu önerilir.", + "Default Upload Mode": "", "Default User Role": "Varsayılan Kullanıcı Rolü", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "Seçimi kaldır", "Detect Artifacts Automatically": "Eserleri Otomatik Algıla", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Dikte Et", "Didn't fully follow instructions": "Talimatları tam olarak takip etmedi", "Direct": "Doğrudan", @@ -838,6 +850,7 @@ "Download as SVG": "SVG olarak İndir", "Download canceled": "İndirme iptal edildi", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "Terminal Bağlantısını Düzenle", "Edit User": "Kullanıcıyı Düzenle", "Edit User Group": "Kullanıcı Grubunu Düzenle", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "workflow.json içeriğini düzenle", "edited": "düzenlendi", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Model tarafından kullanılan akıl yürütme etiketlerini etkinleştirin, devre dışı bırakın veya özelleştirin. \"Etkin\" varsayılan etiketleri kullanır, \"Devre Dışı\" akıl yürütme etiketlerini kapatır ve \"Özel\" kendi başlangıç ve bitiş etiketlerinizi belirtmenize olanak tanır.", "Enabled": "Etkin", + "End call": "", "End Tag": "Bitiş Etiketi", "Endpoint": "", "Endpoint URL": "Uçnokta URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "Üye kaldırılamadı", "Failed to render diagram": "Diyagram oluşturulamadı", "Failed to render visualization": "Görselleştirme oluşturulamadı", + "Failed to save chat variables": "", "Failed to save connections": "Bağlantılar kaydedilemedi", "Failed to save conversation": "Sohbet kaydedilemedi", "Failed to save models configuration": "Modeller yapılandırması kaydedilemedi", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "Klasör başarıyla güncellendi", "Folders": "Klasörler", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "Takip", "Follow Up Generation": "Takip Oluşturma", "Follow Up Generation Prompt": "Takip Oluşturma Prompt'u", @@ -1289,6 +1306,7 @@ "Generate an image": "Bir Görsel Oluştur", "Generate an image prompt before sending the request.": "", "Generate and edit images": "Görseller oluştur ve düzenle", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "Mesaj Çifti Oluştur", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "Kenar Çubuğunda Tut", "Key": "Anahtar", "Key is required": "Anahtar gerekli", + "key_name": "", "Keyboard": "", "Knowledge": "Bilgi", "Knowledge Access": "Bilgi Erişimi", @@ -1540,9 +1559,9 @@ "List": "Liste", "List calendars, search, create, update, and delete calendar events": "Takvimleri listele, takvim etkinliklerini ara, oluştur, güncelle ve sil", "Listening...": "Dinleniyor...", + "LiteLLM": "", "Live": "Canlı", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM'ler hata yapabilir. Önemli bilgileri doğrulayın.", "Loaded": "Yüklendi", "Loader": "Yükleyici", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mart", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown Başlık Metni Bölücü", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' başarıyla indirildi.", "Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' zaten indirme sırasında.", - "Model {{modelId}} not found": "{{modelId}} modeli bulunamadı", "Model {{modelName}} deleted successfully": "{{modelName}} modeli başarıyla silindi", "Model {{modelName}} is not vision capable": "Model {{modelName}} görüntü yeteneğine sahip değil", "Model {{name}} is now {{status}}": "{{name}} modeli artık {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "Yeni Web Kancası", "new-channel": "yeni-kanal", "Next message": "Sonraki mesaj", + "Next month": "", "Next page": "", "Next run": "Sonraki çalıştırma", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "Erişim izni yok. Size özel.", "No actions found": "", "No activity data": "Aktivite verisi yok", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "Bu bilgi tabanında dosya yok.", "No files yet. Upload files or run Python code to create them.": "Henüz dosya yok. Dosya yükleyin veya oluşturmak için Python kodu çalıştırın.", "No filters found": "", + "No folders": "", "No functions found": "Fonksiyon bulunamadı", "No groups found": "Grup bulunamadı", "No history available": "Geçmiş mevcut değil", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "Araç bulunamadı", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Kullanıcı bulunamadı.", "No valves": "Valf yok", "No valves to update": "Güncellenecek valfler yok", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Hay aksi! Hala yüklenen dosyalar var. Yüklemenin tamamlanmasını bekleyin.", "Oops! There was an error in the previous response.": "Hay aksi! Önceki yanıtta bir hata oluştu.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hay aksi! Desteklenmeyen bir yöntem kullanıyorsunuz (yalnızca önyüz). Lütfen WebUI'yi arka uçtan sunun.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Bekleyen Kullanıcı Yer Paylaşımı İçeriği", "Pending User Overlay Title": "Bekleyen Kullanıcı Yer Paylaşımı Başlığı", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Medya cihazlarına erişim izni reddedildi", "Permission denied when accessing microphone": "Mikrofona erişim izni reddedildi", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Önek Kimliği", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Önek Kimliği, model kimliklerine bir önek ekleyerek diğer bağlantılarla çakışmaları önlemek için kullanılır - devre dışı bırakmak için boş bırakın", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "Dosya Oluşturmayı Engelle", "Preview": "Önizleme", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Önceki 30 gün", "Previous 7 days": "Önceki 7 gün", "Previous message": "Önceki mesaj", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Gizli", "Private conversation between selected users": "Seçili kullanıcılar arasında özel konuşma", "Production version updated": "Üretim sürümü güncellendi", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Vektör Depolama/Bilgiyi Sıfırla", "Reset view": "Görünümü sıfırla", "Response": "Yanıt", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Web sitesi izinleri reddedildiğinden yanıt bildirimleri etkinleştirilemiyor. Gerekli erişimi sağlamak için lütfen tarayıcı ayarlarınızı ziyaret edin.", "Response Splitting": "", "Response Watermark": "Yanıt Filigranı", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Sonuç", "RESULT": "Sonuç", + "Retained Messages": "", "Retrieval": "Getirme", "Retrieval Query Generation": "Alıntı Sorgu Oluşturma", "Retrieved {{count}} sources": "{{count}} kaynak alındı", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "Zamanlanan saat gelecekte olmalıdır", "Scopes": "", "Scroll On Branch Change": "Dal Değişiminde Kaydır", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "Başa Kaydır", "Search": "Ara", @@ -2245,6 +2279,7 @@ "Search Files": "Dosyaları Ara", "Search filters": "", "Search Filters": "Filtreleri Ara", + "Search folders": "", "search for archived chats": "arşivlenmiş sohbetleri ara", "search for folders": "klasörleri ara", "search for pinned chats": "sabitlenmiş sohbetleri ara", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "Seçilen model: {{modelName}}", "Selected model(s) do not support image inputs": "Seçilen model(ler) görüntü girişlerini desteklemiyor", + "Selected models define incompatible Chat Variables.": "", "semantic": "semantik", "Send": "Gönder", "Send a Message": "Bir Mesaj Gönder", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "Yeteneklerin Herkese Açık Paylaşımı", "Skills Sharing": "Yeteneklerin Paylaşımı", "Skip Cache": "Önbelleği Atla", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "Bir şeyler yanlış gitti :/", "Sonar": "Sonar", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Adımlar", "Stop": "Durdur", + "Stop camera": "", "Stop Download": "İndirmeyi Durdur", "Stop Generating": "Oluşturmayı Durdur", "Stop Sequence": "Diziyi Durdur", @@ -2516,6 +2554,7 @@ "Support": "Destek", "Support this plugin:": "Bu eklentiyi destekleyin:", "Supported MIME Types": "Desteklenen MIME Türleri", + "Switch camera": "", "Switch to JSON editor": "JSON düzenleyiciye geç", "Switch to visual editor": "Görsel düzenleyiciye geç", "Sync": "Eşitle", @@ -2714,6 +2753,7 @@ "Unmute": "Sesi Aç", "Unpin": "Sabitlemeyi Kaldır", "Unpin from Sidebar": "Kenar Çubuğundan Sabitlemeyi Kaldır", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "Sohbet Paylaşımını Kaldır", @@ -2721,6 +2761,7 @@ "Untagged": "Etiketsiz", "Untitled": "Başlıksız", "Update": "Güncelle", + "Update All Models": "", "Update and Copy Link": "Güncelle ve Bağlantıyı Kopyala", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "kullanıcı", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "Kullanıcı derecelendirmeleri (beğeni/beğenmeme)", "User Status": "Kullanıcı Durumu", + "User Variables": "", "User Webhooks": "Kullanıcı Web Kancaları", "Username": "Kullanıcı Adı", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valfler", "Valves updated": "Valfler güncellendi", "Valves updated successfully": "Valfler başarıyla güncellendi", "variable": "değişken", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Bağlantıyı Doğrula", "Verify SSL Certificate": "SSL Sertifikasını Doğrula", diff --git a/src/lib/i18n/locales/ug-CN/translation.json b/src/lib/i18n/locales/ug-CN/translation.json index 6743d7b720..a61aa5ce36 100644 --- a/src/lib/i18n/locales/ug-CN/translation.json +++ b/src/lib/i18n/locales/ug-CN/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "ئىشلەتكۈچى قوشۇش", "Add User Group": "ئىشلەتكۈچى گۇرۇپپىسى قوشۇش", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "ئىشلەتكۈچى ئورنىنى كۆرسىتىشكە ئىجازەت", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "يېڭى ھەمبەھىرلەنگەن ئۇلانما قۇرۇڭ.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API ئاساسىي URL", "API Key": "API ئاچقۇچى", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "سۆھبەت ھوقۇقلىرى", "Chat Tags Auto-Generation": "سۆھبەت تەغلىرىنى ئاپتوماتىك ھاسىل قىلىش", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "سۆھبەتلەر", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "قايتا تەكشۈرۈش", "Check for updates": "يېڭىلاشنى تەكشۈرۈش", @@ -439,6 +446,7 @@ "Choose a model before saving...": "ساقلاشتىن بۇرۇن مودېل تاللاڭ...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "ئەسلەتمىنى تازىلاش", "Clear Memory": "ئەسلەتمىنى تازىلاش", @@ -563,6 +572,7 @@ "Confirm": "جەزملەش", "Confirm Password": "پارولنى جەزملەش", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "ھەرىكىتىڭىزنى جەزملەڭ", "Confirm your new password": "يېڭى پارولىڭىزنى جەزملەڭ", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "كۆڭۈلدىكى ALL", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "تېخىمۇ مۇناسىپ ۋە مۇھىم مەزمۇن چىقىرىش ئۈچۈن بۆلەكلىك قايتۇرۇش كۆڭۈلدىكى قىلىنغان، كۆپىنچە ئەھۋاللاردا تەۋسىيە قىلىنىدۇ.", + "Default Upload Mode": "", "Default User Role": "كۆڭۈلدىكى ئىشلەتكۈچى رولى", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "ئۇزۇقلارنى ئاپتوماتىك بايقايدۇ", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "سۆزلەش", "Didn't fully follow instructions": "كۆرسىتىلمىلەرگە تولۇق ئەمەل قىلمايدۇ", "Direct": "بىۋاسىتە", @@ -838,6 +850,7 @@ "Download as SVG": "SVG شەكلىدە چۈشۈرۈش", "Download canceled": "چۈشۈرۈش بىكار قىلىندى", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "ئىشلەتكۈچى تەھرىرلەش", "Edit User Group": "ئىشلەتكۈچى گۇرۇپپىسى تەھرىرلەش", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "قوزغىتىلغان", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "ئۇلانما URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "ئۇلىنىشلارنى ساقلاش مەغلۇپ بولدى", "Failed to save conversation": "سۆھبەتنى ساقلاش مەغلۇپ بولدى", "Failed to save models configuration": "مودېل تەڭشەكلىرىنى ساقلاش مەغلۇپ بولدى", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "داۋامى", "Follow Up Generation": "داۋاملاشتۇرۇش ھاسىل قىلىش", "Follow Up Generation Prompt": "داۋاملاشتۇرۇش ھاسىل قىلىش تۈرتكەسى", @@ -1289,6 +1306,7 @@ "Generate an image": "رەسىم ھاسىل قىلىش", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "يانتاختىدا ساقلا", "Key": "ئاچقۇچ", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "بىلىم", "Knowledge Access": "بىلىم زىيارىتى", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "ئاڭلاۋاتىدۇ...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM خاتالىق ئۆتكۈزۈشى مۇمكىن. مۇھىم ئۇچۇرنى تەكشۈرۈڭ.", "Loaded": "", "Loader": "يۈكلىگۈچ", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "مارت", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "مودېل", "Model '{{modelName}}' has been successfully downloaded.": "مودېل '{{modelName}}' مۇۋەپپەقىيەتلىك چۈشۈرۈلدى.", "Model '{{modelTag}}' is already in queue for downloading.": "مودېل '{{modelTag}}' ئاللىقاچان چۈشۈرۈش قاتارىغا قوشۇلغان.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "مودېل {{modelName}} كۆرۈنۈش ئىقتىدارى يوق", "Model {{name}} is now {{status}}": "مودېل {{name}} ھازىر {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "يېڭى-قانال", "Next message": "كېيىنكى ئۇچۇر", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "ئىشلەتكۈچى تېپىلمىدى.", "No valves": "", "No valves to update": "يېڭىلاشقا كېرەكلىك كران يوق", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "ھۆججەت يۈكلەۋاتىدۇ. تولۇق بولغىلىچە كۈتۈڭ.", "Oops! There was an error in the previous response.": "ئالدىنقى ئىنكاستا خاتالىق يۈز بەردى.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "قوللىمايدىغان ئۇسۇل ئىشلىتىلدى (پەقەت ئالدى كۆرۈنۈش). WebUI نى ئارقا سۇپىدىن قوزغىتىڭ.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "كۈتۈۋاتقان ئىشلەتكۈچى قاپلام مەزمۇنى", "Pending User Overlay Title": "كۈتۈۋاتقان ئىشلەتكۈچى قاپلام تېمىسى", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "كۆپ-ۋاستە ئۈسكۈنىلىرىگە كىرىش چەكلەندى", "Permission denied when accessing microphone": "مىكروفونغا كىرىش چەكلەندى", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "باشقا ئۇلىنىش بىلەن توقۇنۇشنىڭ ئالدىنى ئېلىش ئۈچۈن مودېل ID غا Prefix قوشۇلىدۇ - چەكلەش ئۈچۈن بوش قالدۇرۇڭ", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "ئالدىن كۆرۈش", @@ -2043,7 +2071,10 @@ "Previous 30 days": "ئالدىنقى 30 كۈن", "Previous 7 days": "ئالدىنقى 7 كۈن", "Previous message": "ئالدىنقى ئۇچۇر", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "شەخسىي", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "ۋېكتور ساقلاش/بىلىمنى قايتا تەڭشەش", "Reset view": "كۆرۈنۈشنى قايتا تەڭشەش", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "تور بېكەت ھوقۇقى چەكلەنگەنلىكتىن ئىنكاس ئۇقتۇرۇشى قوزغىتىلمايدۇ. تور كۆرگۈچ تەڭشەكلىرىدىن لازىملىق ھوقۇق بېرىڭ.", "Response Splitting": "", "Response Watermark": "ئىنكاس سۇ بەلگىسى", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "نەتىجە", "RESULT": "نەتىجە", + "Retained Messages": "", "Retrieval": "قايتۇرۇش", "Retrieval Query Generation": "قايتۇرۇش سۇئالى ھاسىل قىلىش", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "تارماق ئۆزگەرسە ئېكران يۆتكىلىدۇ", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "ئىزدەش", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "سۈزگۈچ ئىزدەش", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "تاللانغان مودېل(لار) رەسىم كىرگۈزۈشنى قوللىمايدۇ", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "يوللاش", "Send a Message": "ئۇچۇر يوللاڭ", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "غەملەكتىن ئۆتۈپ كېتىش", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "توختات", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "توختاش تىزىقى", @@ -2516,6 +2554,7 @@ "Support": "ياردەم", "Support this plugin:": "بۇ قىستۇرما ئۈچۈن ياردەم قىلىڭ:", "Supported MIME Types": "قوللايدىغان MIME تىپى", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "مۇقىملانمىغان قىلىش", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "تەغسىز", "Untitled": "تېماسىز", "Update": "يېڭىلاش", + "Update All Models": "", "Update and Copy Link": "يېڭىلاش ۋە ئۇلانما كۆچۈرۈش", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "ئىشلەتكۈچى", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "ئىشلەتكۈچى Webhookلىرى", "Username": "ئىشلەتكۈچى نامى", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "كرانلار", "Valves updated": "كرانلار يېڭىلاندى", "Valves updated successfully": "كرانلار مۇۋەپپەقىيەتلىك يېڭىلاندى", "variable": "ئۆزگەرگۈچ", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "ئۇلىنىشنى جەزملەش", "Verify SSL Certificate": "SSL كىنىشكىسىنى جەزملەش", diff --git a/src/lib/i18n/locales/uk-UA/translation.json b/src/lib/i18n/locales/uk-UA/translation.json index 3bbc9b57bd..c08cc350b0 100644 --- a/src/lib/i18n/locales/uk-UA/translation.json +++ b/src/lib/i18n/locales/uk-UA/translation.json @@ -131,6 +131,7 @@ "Add to favorites": "", "Add User": "Додати користувача", "Add User Group": "Додати групу користувачів", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -204,6 +205,7 @@ "Allow User Location": "Доступ до місцезнаходження", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -237,6 +239,7 @@ "and create a new shared link.": "і створіть нове спільне посилання.", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "URL-адреса API", "API Key": "Ключ API", @@ -302,6 +305,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -444,8 +448,11 @@ "Chat Permissions": "Дозволи чату", "Chat Tags Auto-Generation": "Автоматична генерація тегів чату", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Чати", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Перевірити ще раз", "Check for updates": "Перевірити оновлення", @@ -453,6 +460,7 @@ "Choose a model before saving...": "Оберіть модель перед збереженням...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -486,6 +494,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Очистити пам'ять", "Clear Memory": "Очистити пам'ять", @@ -579,6 +588,7 @@ "Confirm": "Підтвердити", "Confirm Password": "Підтвердіть пароль", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Підтвердіть свою дію", "Confirm your new password": "Підтвердіть свій новий пароль", "Confirm Your Password": "", @@ -735,6 +745,7 @@ "Default to ALL": "За замовчуванням — УСІ.", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "За замовчуванням використовувати сегментований пошук для зосередженого та релевантного вилучення контенту, це рекомендується у більшості випадків.", + "Default Upload Mode": "", "Default User Role": "Роль користувача за замовчуванням", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -783,6 +794,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Не повністю дотримувалися інструкцій", "Direct": "Прямий", @@ -854,6 +866,7 @@ "Download as SVG": "Завантажити як SVG", "Download canceled": "Завантаження скасовано", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -901,6 +914,7 @@ "Edit Terminal Connection": "", "Edit User": "Редагувати користувача", "Edit User Group": "Редагувати групу користувачів", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -934,6 +948,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Увімкнено", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1195,6 +1210,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "Не вдалося зберегти розмову", "Failed to save models configuration": "Не вдалося зберегти конфігурацію моделей", @@ -1262,6 +1278,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1309,6 +1326,7 @@ "Generate an image": "Згенерувати зображення", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1487,6 +1505,7 @@ "Keep in Sidebar": "", "Key": "Ключ", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Знання", "Knowledge Access": "Доступ до знань", @@ -1560,9 +1579,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Слухаю...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMs можуть помилятися. Перевірте важливу інформацію.", "Loaded": "", "Loader": "Завантажувач", @@ -1601,6 +1620,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Березень", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1673,7 +1694,6 @@ "Model": "Модель", "Model '{{modelName}}' has been successfully downloaded.": "Модель '{{modelName}}' успішно завантажено.", "Model '{{modelTag}}' is already in queue for downloading.": "Модель '{{modelTag}}' вже знаходиться в черзі на завантаження.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Модель {{modelName}} не здатна бачити", "Model {{name}} is now {{status}}": "Модель {{name}} тепер має {{status}}", @@ -1772,8 +1792,11 @@ "New Webhook": "", "new-channel": "новий-канал", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1804,6 +1827,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1845,6 +1869,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Користувачів не знайдено.", "No valves": "", "No valves to update": "Немає клапанів для оновлення", @@ -1916,6 +1941,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Упс! Деякі файли все ще завантажуються. Будь ласка, зачекайте, поки завантаження завершиться.", "Oops! There was an error in the previous response.": "Упс! Сталася помилка в попередній відповіді.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Упс! Ви використовуєте непідтримуваний метод (тільки для фронтенду). Будь ласка, обслуговуйте WebUI з бекенду.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1993,6 +2019,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Відмовлено в доступі до медіапристроїв", "Permission denied when accessing microphone": "Відмовлено у доступі до мікрофона", @@ -2056,6 +2083,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "ID префікса", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "ID префікса використовується для уникнення конфліктів з іншими підключеннями шляхом додавання префікса до ID моделей — залиште порожнім, щоб вимкнути", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2063,7 +2091,10 @@ "Previous 30 days": "Попередні 30 днів", "Previous 7 days": "Попередні 7 днів", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Приватний", "Private conversation between selected users": "", "Production version updated": "", @@ -2201,6 +2232,7 @@ "Reset Vector Storage/Knowledge": "Скинути векторне сховище/Знання", "Reset view": "Скинути вигляд", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Сповіщення про відповіді не можуть бути активовані, оскільки вам було відмовлено в доступі до веб-сайту. Будь ласка, відвідайте налаштування вашого браузера, щоб надати необхідний доступ.", "Response Splitting": "", "Response Watermark": "", @@ -2209,6 +2241,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Результат", "RESULT": "Результат", + "Retained Messages": "", "Retrieval": "Пошук", "Retrieval Query Generation": "Генерація запиту для отримання даних", "Retrieved {{count}} sources": "", @@ -2255,6 +2288,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Пошук", @@ -2271,6 +2305,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Фільтри пошуку", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2356,6 +2391,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Вибрані модель(і) не підтримують вхідні зображення", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Надіслати", "Send a Message": "Надіслати повідомлення", @@ -2476,6 +2512,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2513,6 +2550,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Зупинити", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Символ зупинки", @@ -2544,6 +2582,7 @@ "Support": "Підтримати", "Support this plugin:": "Підтримайте цей плагін:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2742,6 +2781,7 @@ "Unmute": "", "Unpin": "Відчепити", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2749,6 +2789,7 @@ "Untagged": "Без тегів", "Untitled": "", "Update": "Оновлення", + "Update All Models": "", "Update and Copy Link": "Оновлення та копіювання посилання", "Update Email": "", "Update embedding model": "", @@ -2806,6 +2847,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "користувач", @@ -2820,6 +2862,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Вебхуки користувача", "Username": "Ім'я користувача", "Username Claim": "", @@ -2834,10 +2877,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Клапани", "Valves updated": "Клапани оновлено", "Valves updated successfully": "Клапани успішно оновлено", "variable": "змінна", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Перевірити з'єднання", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/ur-PK/translation.json b/src/lib/i18n/locales/ur-PK/translation.json index cd8527d65d..c3cad5f67a 100644 --- a/src/lib/i18n/locales/ur-PK/translation.json +++ b/src/lib/i18n/locales/ur-PK/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "صارف شامل کریں", "Add User Group": "", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "صارف کی مقام کی اجازت دیں", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "اور ایک نیا مشترکہ لنک بنائیں", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API بنیادی URL", "API Key": "اے پی آئی کلید", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "", "Chat Tags Auto-Generation": "چیٹ ٹیگز خودکار تخلیق", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "بات چیت", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "دوبارہ چیک کریں", "Check for updates": "تازہ ترین معلومات کے لیے چیک کریں", @@ -439,6 +446,7 @@ "Choose a model before saving...": "محفوظ کرنے سے پہلے ایک ماڈل منتخب کریں...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "میموری صاف کریں", "Clear Memory": "", @@ -563,6 +572,7 @@ "Confirm": "تصدیق کریں", "Confirm Password": "پاس ورڈ کی توثیق کریں", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "اپنی کارروائی کی تصدیق کریں", "Confirm your new password": "", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default Upload Mode": "", "Default User Role": "ڈیفالٹ صارف کا کردار", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "ہدایات کو مکمل طور پر نہیں سمجھا", "Direct": "", @@ -838,6 +850,7 @@ "Download as SVG": "", "Download canceled": "ڈاؤن لوڈ منسوخ کر دیا گیا", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "صارف میں ترمیم کریں", "Edit User Group": "", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "فعال کردیا گیا ہے", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "", "Failed to save conversation": "گفتگو محفوظ نہیں ہو سکی", "Failed to save models configuration": "", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "علم", "Knowledge Access": "", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "سن رہے ہیں...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "ایل ایل ایم غلطیاں کر سکتے ہیں اہم معلومات کی تصدیق کریں", "Loaded": "", "Loader": "", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "مارچ", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "ماڈل", "Model '{{modelName}}' has been successfully downloaded.": "ماڈل '{{modelName}}' کامیابی سے ڈاؤن لوڈ ہو گیا ہے", "Model '{{modelTag}}' is already in queue for downloading.": "ماڈل '{{modelTag}}' پہلے ہی ڈاؤن لوڈ کے لیے قطار میں ہے", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "ماڈل {{modelName}} بصری صلاحیت نہیں رکھتا", "Model {{name}} is now {{status}}": "ماڈل {{name}} اب {{status}} ہے", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "", "No valves": "", "No valves to update": "تازہ کاری کے لئے کوئی والو نہیں", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "اوہ! کچھ فائلیں ابھی بھی اپ لوڈ ہو رہی ہیں براہ کرم اپ لوڈ مکمل ہونے کا انتظار کریں", "Oops! There was an error in the previous response.": "اوہ! پچھلے جواب میں ایک غلطی تھی", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "اوہ! آپ ایک غیر معاون طریقہ استعمال کر رہے ہیں (صرف فرنٹ اینڈ) براہ کرم ویب یو آئی کو بیک اینڈ سے پیش کریں", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "میڈیا آلات تک رسائی کے وقت اجازت مسترد کر دی گئی", "Permission denied when accessing microphone": "مائیکروفون تک رسائی کی اجازت نہیں دی گئی", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2043,7 +2071,10 @@ "Previous 30 days": "پچھلے 30 دن", "Previous 7 days": "پچھلے 7 دن", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "ویكٹر اسٹوریج/علم کو ری سیٹ کریں", "Reset view": "", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "جواب کی اطلاعات کو فعال نہیں کیا جا سکتا کیونکہ ویب سائٹ کی اجازتیں مسترد کر دی گئی ہیں براہ کرم اپنے براؤزر کی سیٹنگز پر جائیں تاکہ ضروری رسائی کی اجازت دے سکیں", "Response Splitting": "", "Response Watermark": "", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "نتیجہ", "RESULT": "نتیجہ", + "Retained Messages": "", "Retrieval": "", "Retrieval Query Generation": "", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "تلاش کریں", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "منتخب کردہ ماڈل(ز) تصویری ان پٹ کی حمایت نہیں کرتے", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "بھیجیں", "Send a Message": "پیغام بھیجیں", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "روکیں", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "ترتیب روکیں", @@ -2516,6 +2554,7 @@ "Support": "مدد کریں", "Support this plugin:": "اس پلگ ان کی حمایت کریں:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "ان پن کریں", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "غیر مہر شدہ", "Untitled": "", "Update": "اپ ڈیٹ کریں", + "Update All Models": "", "Update and Copy Link": "اپڈیٹ اور لنک کاپی کریں", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "صارف", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "", "Username": "", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "والو", "Valves updated": "والوز کو اپ ڈیٹ کر دیا گیا", "Valves updated successfully": "والو کامیابی کے ساتھ اپ ڈیٹ ہو گئے", "variable": "متغیر", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json index 7a53b1c660..fc322861d7 100644 --- a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json +++ b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Фойдаланувчи қўшиш", "Add User Group": "Фойдаланувчилар гуруҳини қўшиш", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Фойдаланувчи жойлашувига рухсат бериш", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "ва янги умумий ҳавола яратинг.", "Android": "Андроид", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Дастурий Илова Интерфейси(API) bazaviy URL manzili", "API Key": "Дастурий Илова Интерфейси(API) калити", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Чат рухсатномалари", "Chat Tags Auto-Generation": "Чат тегларини автоматик яратиш", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Суҳбатлар", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Яна текширинг", "Check for updates": "Янгиланишларни текширинг", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Сақлашдан олдин моделни танланг...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Хотирани тозалаш", "Clear Memory": "Хотирани тозалаш", @@ -563,6 +572,7 @@ "Confirm": "Тасдиқланг", "Confirm Password": "Паролни тасдиқланг", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Ҳаракатингизни тасдиқланг", "Confirm your new password": "Янги паролингизни тасдиқланг", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "Барчаси учун бирламчи", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Фокусланган ва тегишли контентни ажратиб олиш учун бирламчи сегментланган қидириш, бу кўп ҳолларда тавсия этилади.", + "Default Upload Mode": "", "Default User Role": "Стандарт фойдаланувчи роли", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Артефактларни автоматик аниқлаш", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Диктация қилиш", "Didn't fully follow instructions": "Кўрсатмаларга тўлиқ амал қилмади", "Direct": "Тўғридан-тўғри", @@ -838,6 +850,7 @@ "Download as SVG": "СВГ сифатида юклаб олинг", "Download canceled": "Юклаб олиш бекор қилинди", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Фойдаланувчини таҳрирлаш", "Edit User Group": "Фойдаланувчилар гуруҳини таҳрирлаш", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Ёқилган", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "Охирги нуқта URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Уланишлар сақланмади", "Failed to save conversation": "Суҳбат сақланмади", "Failed to save models configuration": "Моделлар конфигурацияси сақланмади", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "Тасвир яратиш", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Калит", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Билим", "Knowledge Access": "Билимга кириш", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Тингланмоқда...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Ллама.cпп", "LLMs can make mistakes. Verify important information.": "ЛЛМлар хато қилишлари мумкин. Муҳим маълумотларни тасдиқланг.", "Loaded": "", "Loader": "Юклагич", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Март", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Маркдоwн", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Модел", "Model '{{modelName}}' has been successfully downloaded.": "“{{modelName}}” модели юклаб олинди.", "Model '{{modelTag}}' is already in queue for downloading.": "“{{modelTag}}” модели аллақачон юклаб олиш учун навбатда турибди.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "{{modelName}} модели кўриш қобилиятига эга эмас", "Model {{name}} is now {{status}}": "{{name}} модели энди {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "янги канал", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Ҳеч қандай фойдаланувчи топилмади.", "No valves": "", "No valves to update": "Янгилаш учун клапанлар йўқ", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Вой! Ҳали ҳам файллар юкланмоқда. Илтимос, юклаш тугашини кутинг.", "Oops! There was an error in the previous response.": "Вой! Аввалги жавобда хатолик юз берди.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Вой! Сиз қўллаб-қувватланмайдиган усулдан фойдаланмоқдасиз (фақат фронтенд). Илтимос, WебУИ-га баcкенд орқали хизмат кўрсатинг.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Кутилаётган фойдаланувчи Оверлай контенти", "Pending User Overlay Title": "Кутилаётган фойдаланувчи сарлавҳаси", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Медиа қурилмаларга киришда рухсат рад этилди", "Permission denied when accessing microphone": "Микрофонга киришда рухсат берилмади", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Префикс идентификатори", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Префикс идентификатори модел идентификаторларига префикс қўшиш орқали бошқа уланишлар билан зиддиятларни олдини олиш учун ишлатилади - ўчириш учун бўш қолдиринг.", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Кўриб чиқиш", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Олдинги 30 кун", "Previous 7 days": "Олдинги 7 кун", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Шахсий", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Вектор хотираси/билимини қайта ўрнатиш", "Reset view": "Кўринишни тиклаш", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Жавоб билдиришномаларини фаоллаштириб бўлмайди, чунки веб-сайт рухсатномалари рад этилган. Керакли рухсат бериш учун браузер созламаларига ташриф буюринг.", "Response Splitting": "", "Response Watermark": "Жавоб сув белгиси", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Натижа", "RESULT": "Натижа", + "Retained Messages": "", "Retrieval": "Қидирув", "Retrieval Query Generation": "Қидирув сўровларини яратиш", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Филиални ўзгартириш бўйича айлантиринг", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Қидирув", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Қидирув филтрлари", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Танланган модел(лар) тасвир киритишни қўллаб-қувватламайди", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Юбориш", "Send a Message": "Хабар юбориш", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Кешни ўтказиб юбориш", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "СТОП", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Кетма-кетликни тўхтатиш", @@ -2516,6 +2554,7 @@ "Support": "Қўллаб-қувватлаш", "Support this plugin:": "Ушбу плагинни қўллаб-қувватланг:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Ечиш", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Белгиланмаган", "Untitled": "Сарлавҳасиз", "Update": "Янгилаш", + "Update All Models": "", "Update and Copy Link": "Ҳаволани янгилаш ва нусхалаш", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "фойдаланувчи", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Фойдаланувчи веб-ҳуклари", "Username": "Фойдаланувчи номи", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Ёқиш/Ўчириш параметрлари", "Valves updated": "Ёқиш/Ўчириш параметрлари янгиланди", "Valves updated successfully": "Ёқиш/Ўчириш параметрлари муваффақиятли янгиланди", "variable": "ўзгарувчи ", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Уланишни текширинг", "Verify SSL Certificate": "SSL сертификатини текширинг", diff --git a/src/lib/i18n/locales/uz-Latn-UZ/translation.json b/src/lib/i18n/locales/uz-Latn-UZ/translation.json index 9b91d7c0aa..0a09123b86 100644 --- a/src/lib/i18n/locales/uz-Latn-UZ/translation.json +++ b/src/lib/i18n/locales/uz-Latn-UZ/translation.json @@ -117,6 +117,7 @@ "Add to favorites": "", "Add User": "Foydalanuvchi qo'shish", "Add User Group": "Foydalanuvchilar guruhini qo'shish", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -190,6 +191,7 @@ "Allow User Location": "Foydalanuvchi joylashuviga ruxsat berish", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -223,6 +225,7 @@ "and create a new shared link.": "va yangi umumiy havola yarating.", "Android": "Android", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API bazasi URL", "API Key": "API kaliti", @@ -288,6 +291,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -430,8 +434,11 @@ "Chat Permissions": "Chat ruxsatnomalari", "Chat Tags Auto-Generation": "Chat teglarini avtomatik yaratish", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Suhbatlar", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Yana tekshiring", "Check for updates": "Yangilanishlarni tekshiring", @@ -439,6 +446,7 @@ "Choose a model before saving...": "Saqlashdan oldin modelni tanlang...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -472,6 +480,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Xotirani tozalash", "Clear Memory": "Xotirani tozalash", @@ -563,6 +572,7 @@ "Confirm": "Tasdiqlang", "Confirm Password": "Parolni tasdiqlang", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Harakatingizni tasdiqlang", "Confirm your new password": "Yangi parolingizni tasdiqlang", "Confirm Your Password": "", @@ -719,6 +729,7 @@ "Default to ALL": "ALL uchun birlamchi", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Fokuslangan va tegishli kontentni ajratib olish uchun birlamchi segmentlangan qidirish, bu koʻp hollarda tavsiya etiladi.", + "Default Upload Mode": "", "Default User Role": "Odatiy foydalanuvchi roli", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -767,6 +778,7 @@ "Deselect": "", "Detect Artifacts Automatically": "Artefaktlarni avtomatik aniqlash", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "Diktatsiya qilish", "Didn't fully follow instructions": "Ko'rsatmalarga to'liq amal qilmadi", "Direct": "To'g'ridan-to'g'ri", @@ -838,6 +850,7 @@ "Download as SVG": "SVG sifatida yuklab oling", "Download canceled": "Yuklab olish bekor qilindi", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -885,6 +898,7 @@ "Edit Terminal Connection": "", "Edit User": "Foydalanuvchini tahrirlash", "Edit User Group": "Foydalanuvchilar guruhini tahrirlash", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -918,6 +932,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Yoqilgan", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "Oxirgi nuqta URL", @@ -1175,6 +1190,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Ulanishlar saqlanmadi", "Failed to save conversation": "Suhbat saqlanmadi", "Failed to save models configuration": "Modellar konfiguratsiyasi saqlanmadi", @@ -1242,6 +1258,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1289,6 +1306,7 @@ "Generate an image": "Tasvir yaratish", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1467,6 +1485,7 @@ "Keep in Sidebar": "", "Key": "Kalit", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Bilim", "Knowledge Access": "Bilimga kirish", @@ -1540,9 +1559,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Tinglanmoqda...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLMlar xato qilishlari mumkin. Muhim ma'lumotlarni tasdiqlang.", "Loaded": "", "Loader": "Yuklagich", @@ -1581,6 +1600,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Mart", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "", "Max background": "", @@ -1653,7 +1674,6 @@ "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "“{{modelName}}” modeli yuklab olindi.", "Model '{{modelTag}}' is already in queue for downloading.": "“{{modelTag}}” modeli allaqachon yuklab olish uchun navbatda turibdi.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "{{modelName}} modeli ko'rish qobiliyatiga ega emas", "Model {{name}} is now {{status}}": "{{name}} modeli endi {{status}}", @@ -1752,8 +1772,11 @@ "New Webhook": "", "new-channel": "yangi kanal", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1784,6 +1807,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1825,6 +1849,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Hech qanday foydalanuvchi topilmadi.", "No valves": "", "No valves to update": "Yangilash uchun klapanlar yo'q", @@ -1896,6 +1921,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Voy! Hali ham fayllar yuklanmoqda. Iltimos, yuklash tugashini kuting.", "Oops! There was an error in the previous response.": "Voy! Avvalgi javobda xatolik yuz berdi.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Voy! Siz qoʻllab-quvvatlanmaydigan usuldan foydalanmoqdasiz (faqat frontend). Iltimos, WebUI-ga backend orqali xizmat ko'rsating.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1973,6 +1999,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "Kutilayotgan foydalanuvchi Overlay kontenti", "Pending User Overlay Title": "Kutilayotgan foydalanuvchi sarlavhasi", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Media qurilmalarga kirishda ruxsat rad etildi", "Permission denied when accessing microphone": "Mikrofonga kirishda ruxsat berilmadi", @@ -2036,6 +2063,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Prefiks identifikatori", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefiks identifikatori model identifikatorlariga prefiks qo'shish orqali boshqa ulanishlar bilan ziddiyatlarni oldini olish uchun ishlatiladi - o'chirish uchun bo'sh qoldiring.", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "Ko‘rib chiqish", @@ -2043,7 +2071,10 @@ "Previous 30 days": "Oldingi 30 kun", "Previous 7 days": "Oldingi 7 kun", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Shaxsiy", "Private conversation between selected users": "", "Production version updated": "", @@ -2177,6 +2208,7 @@ "Reset Vector Storage/Knowledge": "Vektor xotirasi/bilimini qayta o'rnatish", "Reset view": "Ko'rinishni tiklash", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Javob bildirishnomalarini faollashtirib bo‘lmaydi, chunki veb-sayt ruxsatnomalari rad etilgan. Kerakli ruxsat berish uchun brauzer sozlamalariga tashrif buyuring.", "Response Splitting": "", "Response Watermark": "Javob suv belgisi", @@ -2185,6 +2217,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Natija", "RESULT": "Natija", + "Retained Messages": "", "Retrieval": "Qidiruv", "Retrieval Query Generation": "Qidiruv so'rovlarini yaratish", "Retrieved {{count}} sources": "", @@ -2229,6 +2262,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "Filialni o'zgartirish bo'yicha aylantiring", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Qidiruv", @@ -2245,6 +2279,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Qidiruv filtrlari", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2330,6 +2365,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Tanlangan model(lar) tasvir kiritishni qo‘llab-quvvatlamaydi", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Yuborish", "Send a Message": "Xabar yuborish", @@ -2450,6 +2486,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "Keshni o'tkazib yuborish", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2485,6 +2522,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "STOP", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Ketma-ketlikni to'xtatish", @@ -2516,6 +2554,7 @@ "Support": "Qo'llab-quvvatlash", "Support this plugin:": "Ushbu plaginni qo'llab-quvvatlang:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2714,6 +2753,7 @@ "Unmute": "", "Unpin": "Yechish", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2721,6 +2761,7 @@ "Untagged": "Belgilanmagan", "Untitled": "Sarlavhasiz", "Update": "Yangilash", + "Update All Models": "", "Update and Copy Link": "Havolani yangilash va nusxalash", "Update Email": "", "Update embedding model": "", @@ -2778,6 +2819,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "foydalanuvchi", @@ -2792,6 +2834,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Foydalanuvchi veb-huklari", "Username": "Foydalanuvchi nomi", "Username Claim": "", @@ -2806,10 +2849,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Vanalar", "Valves updated": "Vanalar yangilandi", "Valves updated successfully": "Vanalar muvaffaqiyatli yangilandi", "variable": "o'zgaruvchan", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Ulanishni tekshiring", "Verify SSL Certificate": "SSL sertifikatini tekshiring", diff --git a/src/lib/i18n/locales/vi-VN/translation.json b/src/lib/i18n/locales/vi-VN/translation.json index b234a02245..36dc13e6a0 100644 --- a/src/lib/i18n/locales/vi-VN/translation.json +++ b/src/lib/i18n/locales/vi-VN/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "", "Add User": "Thêm người dùng", "Add User Group": "Thêm Nhóm Người dùng", + "Add User Variable": "", "Add webhook": "", "Add webpage": "", "Add your Open Terminal URL and API key in Settings → Integrations.": "", @@ -183,6 +184,7 @@ "Allow User Location": "Cho phép sử dụng vị trí người dùng", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "và tạo một link chia sẻ mới", "Android": "", "Anyone": "", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "Đường dẫn tới API (API Base URL)", "API Key": "API Key", @@ -281,6 +284,7 @@ "At time of event": "", "Attach File From Knowledge": "", "Attach Files": "", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "", "Attach Notes": "", "Attach Webpage": "", @@ -423,8 +427,11 @@ "Chat Permissions": "Quyền Chat", "Chat Tags Auto-Generation": "Tự động tạo Thẻ Chat", "Chat unshared successfully.": "", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "", "Chats": "Chat", + "Chats Open Sharing": "", "Chats Public Sharing": "", "Check Again": "Kiểm tra Lại", "Check for updates": "Kiểm tra cập nhật", @@ -432,6 +439,7 @@ "Choose a model before saving...": "Chọn mô hình trước khi lưu...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "Xóa bộ nhớ", "Clear Memory": "Xóa Bộ nhớ", @@ -555,6 +564,7 @@ "Confirm": "Xác nhận", "Confirm Password": "Xác nhận Mật khẩu", "Confirm Prompt from Embed": "", + "Confirm recording": "", "Confirm your action": "Xác nhận hành động của bạn", "Confirm your new password": "Xác nhận mật khẩu mới của bạn", "Confirm Your Password": "", @@ -711,6 +721,7 @@ "Default to ALL": "Mặc định là TẤT CẢ", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Mặc định truy xuất phân đoạn để trích xuất nội dung tập trung và phù hợp, điều này được khuyến nghị cho hầu hết các trường hợp.", + "Default Upload Mode": "", "Default User Role": "Vai trò mặc định", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "", "Detect Artifacts Automatically": "", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "", "Didn't fully follow instructions": "Không tuân theo chỉ dẫn một cách đầy đủ", "Direct": "Trực tiếp", @@ -830,6 +842,7 @@ "Download as SVG": "Tải xuống dưới dạng SVG", "Download canceled": "Đã hủy download", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "", "Edit User": "Thay đổi thông tin người sử dụng", "Edit User Group": "Chỉnh sửa Nhóm Người dùng", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "", "edited": "", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Đã bật", + "End call": "", "End Tag": "", "Endpoint": "", "Endpoint URL": "", @@ -1165,6 +1180,7 @@ "Failed to remove member": "", "Failed to render diagram": "", "Failed to render visualization": "", + "Failed to save chat variables": "", "Failed to save connections": "Không thể lưu các kết nối", "Failed to save conversation": "Không thể lưu cuộc trò chuyện", "Failed to save models configuration": "Không thể lưu cấu hình mô hình", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "", "Folders": "", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "", "Follow Up Generation": "", "Follow Up Generation Prompt": "", @@ -1279,6 +1296,7 @@ "Generate an image": "Tạo một hình ảnh", "Generate an image prompt before sending the request.": "", "Generate and edit images": "", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "", "Key": "Khóa", "Key is required": "", + "key_name": "", "Keyboard": "", "Knowledge": "Kiến thức", "Knowledge Access": "Truy cập Kiến thức", @@ -1530,9 +1549,9 @@ "List": "", "List calendars, search, create, update, and delete calendar events": "", "Listening...": "Đang nghe...", + "LiteLLM": "", "Live": "", "llama.cpp": "", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Hệ thống có thể tạo ra nội dung không chính xác hoặc sai. Hãy kiểm chứng kỹ lưỡng thông tin trước khi tiếp nhận và sử dụng.", "Loaded": "", "Loader": "Trình tải", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "Tháng 3", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "", "Markdown Header Text Splitter": "", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "Mô hình", "Model '{{modelName}}' has been successfully downloaded.": "Mô hình '{{modelName}}' đã được tải xuống thành công.", "Model '{{modelTag}}' is already in queue for downloading.": "Mô hình '{{modelTag}}' đã có trong hàng đợi để tải xuống.", - "Model {{modelId}} not found": "", "Model {{modelName}} deleted successfully": "", "Model {{modelName}} is not vision capable": "Model {{modelName}} không có khả năng nhìn", "Model {{name}} is now {{status}}": "Model {{name}} bây giờ là {{status}}", @@ -1742,8 +1762,11 @@ "New Webhook": "", "new-channel": "kênh-mới", "Next message": "", + "Next month": "", "Next page": "", "Next run": "", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "", "No actions found": "", "No activity data": "", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "", "No files yet. Upload files or run Python code to create them.": "", "No filters found": "", + "No folders": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1815,6 +1839,7 @@ "No tools accessible": "", "No tools found": "", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "Không tìm thấy người dùng nào.", "No valves": "", "No valves to update": "Chưa có valves nào được cập nhật", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "Ối! Vẫn còn tệp đang tải lên. Vui lòng đợi quá trình tải lên hoàn tất.", "Oops! There was an error in the previous response.": "Ối! Đã xảy ra lỗi trong phản hồi trước đó.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Rất tiếc! Bạn đang sử dụng một phương thức không được hỗ trợ (chỉ dành cho frontend). Vui lòng cung cấp phương thức cho WebUI từ phía backend.", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "", "Pending User Overlay Title": "", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "Quyền truy cập các thiết bị đa phương tiện bị từ chối", "Permission denied when accessing microphone": "Quyền truy cập micrô bị từ chối", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "Tiền tố ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Tiền tố ID được sử dụng để tránh xung đột với các kết nối khác bằng cách thêm tiền tố vào ID mô hình - để trống để tắt", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "", "Preview": "", @@ -2033,7 +2061,10 @@ "Previous 30 days": "30 ngày trước", "Previous 7 days": "7 ngày trước", "Previous message": "", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "Riêng tư", "Private conversation between selected users": "", "Production version updated": "", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "Đặt lại Lưu trữ Vector/Kiến thức", "Reset view": "Đặt lại chế độ xem", "Response": "", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Không thể kích hoạt thông báo vì trang web không cấp quyền. Vui lòng truy cập cài đặt trình duyệt của bạn để cấp quyền cần thiết.", "Response Splitting": "", "Response Watermark": "", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "Kết quả", "RESULT": "Kết quả", + "Retained Messages": "", "Retrieval": "Truy xuất", "Retrieval Query Generation": "Tạo Truy vấn Truy xuất", "Retrieved {{count}} sources": "", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "", "Scopes": "", "Scroll On Branch Change": "", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "", "Search": "Tìm kiếm", @@ -2232,6 +2266,7 @@ "Search Files": "", "Search filters": "", "Search Filters": "Bộ lọc Tìm kiếm", + "Search folders": "", "search for archived chats": "", "search for folders": "", "search for pinned chats": "", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "", "Selected model(s) do not support image inputs": "Model được lựa chọn không hỗ trợ đầu vào là hình ảnh", + "Selected models define incompatible Chat Variables.": "", "semantic": "", "Send": "Gửi", "Send a Message": "Gửi yêu cầu", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "", "Skills Sharing": "", "Skip Cache": "", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "", "Sonar": "", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "Dừng", + "Stop camera": "", "Stop Download": "", "Stop Generating": "", "Stop Sequence": "Trình tự Dừng", @@ -2502,6 +2540,7 @@ "Support": "Hỗ trợ", "Support this plugin:": "Hỗ trợ plugin này:", "Supported MIME Types": "", + "Switch camera": "", "Switch to JSON editor": "", "Switch to visual editor": "", "Sync": "", @@ -2700,6 +2739,7 @@ "Unmute": "", "Unpin": "Bỏ ghim", "Unpin from Sidebar": "", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "", @@ -2707,6 +2747,7 @@ "Untagged": "Chưa gắn thẻ", "Untitled": "", "Update": "Cập nhật", + "Update All Models": "", "Update and Copy Link": "Cập nhật và sao chép link", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "Người sử dụng", @@ -2778,6 +2820,7 @@ "User Preview": "", "User ratings (thumbs up/down)": "", "User Status": "", + "User Variables": "", "User Webhooks": "Webhook Người dùng", "Username": "Tên đăng nhập", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "Valves", "Valves updated": "Đã cập nhật Valves", "Valves updated successfully": "Đã cập nhật Valves thành công", "variable": "biến", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "Xác minh Kết nối", "Verify SSL Certificate": "", diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 74062c6f71..b4aff75337 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "添加到收藏", "Add User": "添加用户", "Add User Group": "添加用户组", + "Add User Variable": "", "Add webhook": "", "Add webpage": "添加网页", "Add your Open Terminal URL and API key in Settings → Integrations.": "请到“设置 → 集成”中配置 Open Terminal 的地址和密钥。", @@ -183,6 +184,7 @@ "Allow User Location": "获取您的位置", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "并创建新的分享链接", "Android": "Android", "Anyone": "任何人", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "接口地址", "API Key": "API 密钥", @@ -281,6 +284,7 @@ "At time of event": "事件开始时", "Attach File From Knowledge": "引用知识库中的文件", "Attach Files": "添加文件", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "引用知识库", "Attach Notes": "引用笔记", "Attach Webpage": "引用网页", @@ -423,8 +427,11 @@ "Chat Permissions": "对话权限", "Chat Tags Auto-Generation": "自动生成对话标签", "Chat unshared successfully.": "已成功取消分享对话。", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "对话", "Chats": "对话", + "Chats Open Sharing": "", "Chats Public Sharing": "对话公开分享", "Check Again": "刷新重试", "Check for updates": "检查更新", @@ -432,6 +439,7 @@ "Choose a model before saving...": "保存前选择一个模型...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "清除记忆", "Clear Memory": "清除记忆", @@ -555,6 +564,7 @@ "Confirm": "确认", "Confirm Password": "确认密码", "Confirm Prompt from Embed": "确认嵌入提示词", + "Confirm recording": "", "Confirm your action": "确认要继续吗?", "Confirm your new password": "确认新密码", "Confirm Your Password": "确认您的密码", @@ -711,6 +721,7 @@ "Default to ALL": "默认为:ALL", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "默认进行分段检索以提取重点和相关内容(推荐)", + "Default Upload Mode": "", "Default User Role": "默认用户角色", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "取消选中", "Detect Artifacts Automatically": "自动检测对话产物", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "语音输入", "Didn't fully follow instructions": "没有完全遵循指令", "Direct": "直接", @@ -830,6 +842,7 @@ "Download as SVG": "下载为 SVG", "Download canceled": "下载已取消", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "编辑终端连接", "Edit User": "编辑用户", "Edit User Group": "编辑用户组", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "编辑 workflow.json", "edited": "已编辑", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "启用、禁用或自定义模型使用的推理过程标签。“启用”表示使用默认标签,“禁用”将不识别推理标签,“自定义”可指定起始和闭合标签。", "Enabled": "已启用", + "End call": "", "End Tag": "结束标签", "Endpoint": "", "Endpoint URL": "接口地址", @@ -1165,6 +1180,7 @@ "Failed to remove member": "移除成员失败", "Failed to render diagram": "图表渲染失败", "Failed to render visualization": "图表渲染失败", + "Failed to save chat variables": "", "Failed to save connections": "保存连接失败", "Failed to save conversation": "保存对话失败", "Failed to save models configuration": "保存模型配置失败", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "分组更新成功", "Folders": "分组", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "追问", "Follow Up Generation": "追问生成", "Follow Up Generation Prompt": "追问生成提示词", @@ -1279,6 +1296,7 @@ "Generate an image": "生成图像", "Generate an image prompt before sending the request.": "", "Generate and edit images": "生成和编辑图像", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "生成消息对", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "保留在侧边栏", "Key": "密匙", "Key is required": "密匙是必填项。", + "key_name": "", "Keyboard": "", "Knowledge": "知识库", "Knowledge Access": "访问知识库", @@ -1530,9 +1549,9 @@ "List": "列表", "List calendars, search, create, update, and delete calendar events": "列出日程,并可搜索、创建、更新和删除日程事件", "Listening...": "正在倾听...", + "LiteLLM": "", "Live": "实时", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "大语言模型可能会犯错,请核实关键信息。", "Loaded": "已加载", "Loader": "加载器", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "三月", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown 标题文本分割器", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "模型", "Model '{{modelName}}' has been successfully downloaded.": "模型“{{modelName}}”已成功下载", "Model '{{modelTag}}' is already in queue for downloading.": "模型“{{modelTag}}”已在下载队列中", - "Model {{modelId}} not found": "未找到模型 {{modelId}}", "Model {{modelName}} deleted successfully": "成功删除模型:{{modelName}}", "Model {{modelName}} is not vision capable": "模型 {{modelName}} 不支持视觉能力", "Model {{name}} is now {{status}}": "模型 {{name}} 现在是 {{status}}", @@ -1742,8 +1762,11 @@ "New Webhook": "新建 Webhook", "new-channel": "新频道", "Next message": "下一条消息", + "Next month": "", "Next page": "", "Next run": "下次运行", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "未共享给他人,仅你可访问。", "No actions found": "", "No activity data": "没有活动数据", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "此知识库中没有文件。", "No files yet. Upload files or run Python code to create them.": "暂无文件。请上传文件或运行 Python 代码以创建文件。", "No filters found": "", + "No folders": "", "No functions found": "未找到函数", "No groups found": "暂无用户组", "No history available": "暂无历史记录", @@ -1815,6 +1839,7 @@ "No tools accessible": "没有可访问的工具", "No tools found": "未找到工具", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "未找到用户", "No valves": "没有配置项", "No valves to update": "没有需要更新的配置项", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "仍有文件正在上传。请等待上传完成。", "Oops! There was an error in the previous response.": "抱歉,先前的回答中出现了错误,请尝试重新生成或新开对话。", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "您正在使用不受支持的方法(仅运行前端服务)。请通过后端服务提供 WebUI。", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "待激活用户界面内容", "Pending User Overlay Title": "待激活用户界面标题", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "申请媒体设备权限被拒绝", "Permission denied when accessing microphone": "申请麦克风权限被拒绝", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "模型 ID 前缀", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "在模型 ID 前添加前缀以避免与其它连接提供的模型冲突。留空则禁用此功能。", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "阻止文件创建", "Preview": "预览", @@ -2033,7 +2061,10 @@ "Previous 30 days": "过去 30 天", "Previous 7 days": "过去 7 天", "Previous message": "上一条消息", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "私有", "Private conversation between selected users": "所选用户之间的私密对话", "Production version updated": "当前使用版本已更新", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "重置向量存储/知识", "Reset view": "重置视图", "Response": "回答", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "无法启用生成结果通知。请检查浏览器设置,并授予必要的访问权限。", "Response Splitting": "", "Response Watermark": "复制时添加水印", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "结果", "RESULT": "结果", + "Retained Messages": "", "Retrieval": "检索", "Retrieval Query Generation": "检索查询生成", "Retrieved {{count}} sources": "检索到 {{count}} 个引用来源", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "定时时间必须晚于当前时间", "Scopes": "", "Scroll On Branch Change": "切换对话分支时滚动到最新回答", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "回到顶部", "Search": "搜索", @@ -2232,6 +2266,7 @@ "Search Files": "搜索文件", "Search filters": "", "Search Filters": "搜索过滤器", + "Search folders": "", "search for archived chats": "搜索已归档的对话", "search for folders": "搜索分组", "search for pinned chats": "搜索已置顶的对话", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "已选择:{{modelName}}", "Selected model(s) do not support image inputs": "所选择的模型不支持处理图像", + "Selected models define incompatible Chat Variables.": "", "semantic": "语义", "Send": "发送", "Send a Message": "输入消息", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "公开分享“技能”", "Skills Sharing": "分享“技能”", "Skip Cache": "跳过缓存", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "发生错误", "Sonar": "Sonar", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "标准输出/标准错误", "Steps": "迭代步数", "Stop": "停止", + "Stop camera": "", "Stop Download": "停止下载", "Stop Generating": "停止生成", "Stop Sequence": "停止序列 (Stop Sequence)", @@ -2502,6 +2540,7 @@ "Support": "支持", "Support this plugin:": "支持此插件", "Supported MIME Types": "支持的 MIME 类型", + "Switch camera": "", "Switch to JSON editor": "切换到 JSON 编辑器", "Switch to visual editor": "切换到可视化编辑器", "Sync": "同步", @@ -2700,6 +2739,7 @@ "Unmute": "取消静音", "Unpin": "取消置顶", "Unpin from Sidebar": "从侧边栏取消固定", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "取消分享对话", @@ -2707,6 +2747,7 @@ "Untagged": "无标签", "Untitled": "无标题", "Update": "更新", + "Update All Models": "", "Update and Copy Link": "更新和复制链接", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "用户", @@ -2778,6 +2820,7 @@ "User Preview": "用户预览", "User ratings (thumbs up/down)": "用户评分(赞/踩)", "User Status": "用户状态", + "User Variables": "", "User Webhooks": "用户 Webhook", "Username": "用户名", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "配置项", "Valves updated": "配置项已更新", "Valves updated successfully": "配置项更新成功", "variable": "变量", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "验证连接", "Verify SSL Certificate": "验证 SSL 证书", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index 17ff77fb20..f8ce5ea858 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -110,6 +110,7 @@ "Add to favorites": "新增至收藏", "Add User": "新增使用者", "Add User Group": "新增使用者群組", + "Add User Variable": "", "Add webhook": "", "Add webpage": "新增網頁", "Add your Open Terminal URL and API key in Settings → Integrations.": "請至「設定 → 整合」中設定 Open Terminal 的網址與 API 金鑰。", @@ -183,6 +184,7 @@ "Allow User Location": "允許使用者位置", "Allow users to access calendar features.": "", "Allow users to authenticate with an LDAP directory.": "", + "Allow users to authenticate with an OAuth / OIDC provider.": "", "Allow users to configure webhooks from their account.": "", "Allow users to create accounts through OAuth.": "", "Allow users to create and manage notes.": "", @@ -216,6 +218,7 @@ "and create a new shared link.": "並建立新的共用連結。", "Android": "Android", "Anyone": "任何人", + "Anyone with the link can view": "", "API Auth String": "", "API Base URL": "API 基礎 URL", "API Key": "API 金鑰", @@ -281,6 +284,7 @@ "At time of event": "活動開始時", "Attach File From Knowledge": "從知識庫附加檔案", "Attach Files": "新增檔案", + "Attach files with full content or focused retrieval by default.": "", "Attach Knowledge": "附加知識庫", "Attach Notes": "附加筆記", "Attach Webpage": "附加網頁", @@ -423,8 +427,11 @@ "Chat Permissions": "對話權限", "Chat Tags Auto-Generation": "自動產生對話標籤", "Chat unshared successfully.": "已成功取消分享對話。", + "Chat Variables": "", + "Chat Variables have conflicting model definitions": "", "chats": "對話", "Chats": "對話", + "Chats Open Sharing": "", "Chats Public Sharing": "對話公開分享", "Check Again": "再次檢查", "Check for updates": "檢查更新", @@ -432,6 +439,7 @@ "Choose a model before saving...": "儲存前請選擇一個模型...", "Choose automatic, left-to-right, or right-to-left text flow.": "", "Choose fallback models for background tasks. Current Model follows the active chat model.": "", + "Choose folder": "", "Choose how extracted text is split before indexing.": "", "Choose how uploaded documents are parsed before indexing.": "", "Choose how web result pages are fetched and read.": "", @@ -465,6 +473,7 @@ "Claim used as the profile picture URL.": "", "Claim used as the stable user identifier.": "", "Claim used as the user email address.": "", + "Clear": "", "Clear filters to reorder": "", "Clear memory": "清除記憶", "Clear Memory": "清除記憶", @@ -555,6 +564,7 @@ "Confirm": "確認", "Confirm Password": "確認密碼", "Confirm Prompt from Embed": "確認嵌入提示詞", + "Confirm recording": "", "Confirm your action": "確認您的操作", "Confirm your new password": "確認您的新密碼", "Confirm Your Password": "確認您的密碼", @@ -711,6 +721,7 @@ "Default to ALL": "預設到所有", "Default to memberOf": "", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "預設使用分段檢索以提取聚焦且相關的內容,建議用於大多數情況。", + "Default Upload Mode": "", "Default User Role": "預設使用者角色", "Default webhook": "", "Defines the behavior used for spoken conversations.": "", @@ -759,6 +770,7 @@ "Deselect": "取消選取", "Detect Artifacts Automatically": "自動偵測對話產物", "Detect generated artifacts and show them in the artifact workspace.": "", + "Detected Variables": "", "Dictate": "語音輸入", "Didn't fully follow instructions": "未完全遵循指示", "Direct": "直接", @@ -830,6 +842,7 @@ "Download as SVG": "以 SVG 格式下載", "Download canceled": "已取消下載", "Download every user's chat history as JSON.": "", + "Download failed": "", "Download the application database when supported.": "", "Download the current admin configuration as JSON.": "", "Download your chat history as a JSON export.": "", @@ -877,6 +890,7 @@ "Edit Terminal Connection": "編輯終端連線", "Edit User": "編輯使用者", "Edit User Group": "編輯使用者群組", + "Edit User Variable": "", "Edit webhook": "", "Edit workflow.json content": "編輯 workflow.json 內容", "edited": "已編輯", @@ -910,6 +924,7 @@ "Enable Web Search": "", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "啟用、停用或自訂模型的推理標籤。「啟用」將使用預設的推理標籤,「停用」則不使用推理標籤,「自訂」允許您指定模型推理過程的起始與結束標籤。", "Enabled": "已啟用", + "End call": "", "End Tag": "結束標籤", "Endpoint": "", "Endpoint URL": "端點 URL", @@ -1165,6 +1180,7 @@ "Failed to remove member": "移除成員失敗", "Failed to render diagram": "繪製圖表失敗", "Failed to render visualization": "繪製圖表失敗", + "Failed to save chat variables": "", "Failed to save connections": "儲存連線失敗", "Failed to save conversation": "儲存對話失敗", "Failed to save models configuration": "儲存模型設定失敗", @@ -1232,6 +1248,7 @@ "Folder updated successfully": "分組更新成功", "Folders": "分組", "Folders Sharing": "", + "Follow assistant responses as they are generated.": "", "Follow up": "跟進", "Follow Up Generation": "跟進內容產生", "Follow Up Generation Prompt": "跟進內容產生提示詞", @@ -1279,6 +1296,7 @@ "Generate an image": "產生圖片", "Generate an image prompt before sending the request.": "", "Generate and edit images": "生成和編輯圖片", + "Generate message pair": "", "Generate chat titles automatically from conversation content.": "", "Generate Message Pair": "產生訊息對", "Generate suggested follow-up prompts after responses.": "", @@ -1457,6 +1475,7 @@ "Keep in Sidebar": "保留在側邊欄", "Key": "金鑰", "Key is required": "金鑰為必填項目", + "key_name": "", "Keyboard": "", "Knowledge": "知識庫", "Knowledge Access": "知識庫存取", @@ -1530,9 +1549,9 @@ "List": "列表", "List calendars, search, create, update, and delete calendar events": "列出日程,並可搜尋、新增、更新與刪除日程活動", "Listening...": "正在聆聽...", + "LiteLLM": "", "Live": "即時", "llama.cpp": "llama.cpp", - "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "大型語言模型可能會犯錯。請自行驗證重要資訊。", "Loaded": "已載入", "Loader": "載入工具", @@ -1571,6 +1590,8 @@ "Map workflow node inputs used for image generation.": "", "Mapped Source": "", "March": "3 月", + "Mark all as read": "", + "Mark as unread": "", "Markdown": "Markdown", "Markdown Header Text Splitter": "Markdown 標題文字分割器", "Max background": "", @@ -1643,7 +1664,6 @@ "Model": "模型", "Model '{{modelName}}' has been successfully downloaded.": "模型「{{modelName}}」已成功下載。", "Model '{{modelTag}}' is already in queue for downloading.": "模型「{{modelTag}}」已在下載佇列中。", - "Model {{modelId}} not found": "找不到模型 {{modelId}}", "Model {{modelName}} deleted successfully": "模型 {{modelName}} 已成功刪除", "Model {{modelName}} is not vision capable": "模型 {{modelName}} 不具備視覺能力", "Model {{name}} is now {{status}}": "模型 {{name}} 現在狀態為 {{status}}", @@ -1742,8 +1762,11 @@ "New Webhook": "新增 Webhook", "new-channel": "新頻道", "Next message": "下一條訊息", + "Next month": "", "Next page": "", "Next run": "下次執行", + "Next slide": "", + "Next version": "", "No access grants. Private to you.": "未分享給他人,僅你可存取。", "No actions found": "", "No activity data": "沒有活動資料", @@ -1774,6 +1797,7 @@ "No files in this knowledge base.": "此知識庫中沒有檔案。", "No files yet. Upload files or run Python code to create them.": "尚無檔案。請上傳檔案或執行 Python 程式碼以建立檔案。", "No filters found": "", + "No folders": "", "No functions found": "未找到函式", "No groups found": "暫無權限群組", "No history available": "暫無歷史紀錄", @@ -1815,6 +1839,7 @@ "No tools accessible": "無可存取的工具", "No tools found": "未找到工具", "No usage data found": "", + "No user variables configured.": "", "No users were found.": "未找到任何使用者", "No valves": "沒有設定項目", "No valves to update": "沒有可更新的設定項目", @@ -1886,6 +1911,7 @@ "Oops! There are files still uploading. Please wait for the upload to complete.": "哎呀!還有檔案正在上傳。請等候上傳完畢。", "Oops! There was an error in the previous response.": "哎呀!之前的回應有一處錯誤。", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "哎呀!您使用了不支援的方法(僅限前端)。請從後端提供 WebUI。", + "Open": "", "Open automation": "", "Open create menu": "", "Open detail blocks by default.": "", @@ -1963,6 +1989,7 @@ "Pending Accounts": "", "Pending User Overlay Content": "待處理的使用者訊息覆蓋層內容", "Pending User Overlay Title": "待處理的使用者訊息覆蓋層標題", + "Percentage of recent messages to keep after older messages are summarized.": "", "Permanently delete every chat after confirmation.": "", "Permission denied when accessing media devices": "存取媒體裝置時權限遭拒", "Permission denied when accessing microphone": "存取麥克風時權限遭拒", @@ -2026,6 +2053,7 @@ "Preferred transcript language codes, separated by commas.": "", "Prefix ID": "前置 ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "前置 ID 用於透過為模型 ID 新增字首以避免與其他連線衝突 - 留空以停用", + "Preparing download...": "", "Press keys...": "", "Prevent File Creation": "阻止檔案建立", "Preview": "預覽", @@ -2033,7 +2061,10 @@ "Previous 30 days": "過去 30 天", "Previous 7 days": "過去 7 天", "Previous message": "過去訊息", + "Previous month": "", "Previous page": "", + "Previous slide": "", + "Previous version": "", "Private": "私有", "Private conversation between selected users": "特定使用者之間的私人對話", "Production version updated": "目前使用版本已更新", @@ -2165,6 +2196,7 @@ "Reset Vector Storage/Knowledge": "重設向量儲存或知識", "Reset view": "重設檢視", "Response": "回應", + "Response Auto-Scroll": "", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "無法啟用回應通知,因為網站權限已遭拒。請前往瀏覽器設定以授予必要存取權限。", "Response Splitting": "", "Response Watermark": "回應浮水印", @@ -2173,6 +2205,7 @@ "Restrict or exclude domains using a comma-separated list.": "", "Result": "結果", "RESULT": "結果", + "Retained Messages": "", "Retrieval": "檢索", "Retrieval Query Generation": "檢索查詢生成", "Retrieved {{count}} sources": "搜尋到 {{count}} 個來源", @@ -2216,6 +2249,7 @@ "Scheduled time must be in the future": "排程時間必須晚於目前時間", "Scopes": "", "Scroll On Branch Change": "切換分支時自動捲動", + "Scroll to bottom": "", "Scroll to the active branch when switching response branches.": "", "Scroll to Top": "回到頂部", "Search": "搜尋", @@ -2232,6 +2266,7 @@ "Search Files": "搜尋檔案", "Search filters": "", "Search Filters": "搜尋篩選器", + "Search folders": "", "search for archived chats": "搜尋已封存的聊天", "search for folders": "搜尋分組", "search for pinned chats": "搜尋已釘選的聊天", @@ -2317,6 +2352,7 @@ "Selected": "", "Selected model: {{modelName}}": "已選擇:{{modelName}}", "Selected model(s) do not support image inputs": "選取的模型不支援圖片輸入", + "Selected models define incompatible Chat Variables.": "", "semantic": "語義", "Send": "傳送", "Send a Message": "傳送訊息", @@ -2437,6 +2473,7 @@ "Skills Public Sharing": "公開分享「技能」", "Skills Sharing": "分享「技能」", "Skip Cache": "略過快取", + "Skip to main content": "", "Skip cached Marker results and rerun inference.": "", "Something went wrong :/": "發生錯誤 :/", "Sonar": "Sonar", @@ -2471,6 +2508,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "迭代步數", "Stop": "停止", + "Stop camera": "", "Stop Download": "停止下載", "Stop Generating": "停止產生", "Stop Sequence": "停止序列", @@ -2502,6 +2540,7 @@ "Support": "支援", "Support this plugin:": "支援這個外掛:", "Supported MIME Types": "支援的 MIME 類型", + "Switch camera": "", "Switch to JSON editor": "切換至 JSON 編輯器", "Switch to visual editor": "切換至視覺化編輯器", "Sync": "同步", @@ -2700,6 +2739,7 @@ "Unmute": "取消靜音", "Unpin": "取消釘選", "Unpin from Sidebar": "從側邊欄取消釘選", + "Unread": "", "Unshare All": "", "Unshare All Shared Chats": "", "Unshare Chat": "取消分享對話", @@ -2707,6 +2747,7 @@ "Untagged": "無標籤", "Untitled": "未命名", "Update": "更新", + "Update All Models": "", "Update and Copy Link": "更新並複製連結", "Update Email": "", "Update embedding model": "", @@ -2764,6 +2805,7 @@ "Use styled formatting when exporting chats to PDF.": "", "Use the active chat title as the browser tab title.": "", "Use the rich composer instead of a plain textarea.": "", + "Use these in model system prompts as {{example}}.": "", "Use TLS when connecting to the LDAP server.": "", "Use Web Search?": "", "user": "使用者", @@ -2778,6 +2820,7 @@ "User Preview": "使用者預覽", "User ratings (thumbs up/down)": "使用者評分(讚/踩)", "User Status": "使用者狀態", + "User Variables": "", "User Webhooks": "使用者 Webhooks", "Username": "使用者名稱", "Username Claim": "", @@ -2792,10 +2835,15 @@ "Valid time units: 's', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "", "Validate Certificate": "", "Validate SSL certificates when fetching web content.": "", + "Value": "", "Valves": "設定項目", "Valves updated": "設定項目已更新", "Valves updated successfully": "設定項目成功更新", "variable": "變數", + "Variable key": "", + "Variable keys must be unique.": "", + "Variable keys must use lowercase snake case.": "", + "Variable value": "", "Vector Field": "", "Verify Connection": "驗證連線", "Verify SSL Certificate": "驗證 SSL 憑證", diff --git a/src/lib/shortcuts.ts b/src/lib/shortcuts.ts index b2c94ad38a..1e60ae7928 100644 --- a/src/lib/shortcuts.ts +++ b/src/lib/shortcuts.ts @@ -23,12 +23,15 @@ export enum Shortcut { DELETE_CHAT = 'deleteChat', OPEN_MODEL_SELECTOR = 'openModelSelector', TOGGLE_DICTATION = 'toggleDictation', + NAVIGATE_CHAT_UP = 'navigateChatUp', + NAVIGATE_CHAT_DOWN = 'navigateChatDown', //Global SEARCH = 'search', OPEN_SETTINGS = 'openSettings', SHOW_SHORTCUTS = 'showShortcuts', TOGGLE_SIDEBAR = 'toggleSidebar', + TOGGLE_CONTROLS = 'toggleControls', CLOSE_MODAL = 'closeModal', //Input @@ -57,10 +60,13 @@ export const CONFIGURABLE_SHORTCUTS = [ Shortcut.DELETE_CHAT, Shortcut.OPEN_MODEL_SELECTOR, Shortcut.TOGGLE_DICTATION, + Shortcut.NAVIGATE_CHAT_UP, + Shortcut.NAVIGATE_CHAT_DOWN, Shortcut.SEARCH, Shortcut.OPEN_SETTINGS, Shortcut.SHOW_SHORTCUTS, Shortcut.TOGGLE_SIDEBAR, + Shortcut.TOGGLE_CONTROLS, Shortcut.CLOSE_MODAL, Shortcut.FOCUS_INPUT, Shortcut.GENERATE_MESSAGE_PAIR, @@ -78,10 +84,13 @@ export const DEFAULT_KEYBINDINGS: KeybindingsMap = { [Shortcut.DELETE_CHAT]: 'Cmd+Shift+Backspace', [Shortcut.OPEN_MODEL_SELECTOR]: 'Cmd+Shift+M', [Shortcut.TOGGLE_DICTATION]: 'Cmd+Shift+L', + [Shortcut.NAVIGATE_CHAT_UP]: '', + [Shortcut.NAVIGATE_CHAT_DOWN]: '', [Shortcut.SEARCH]: 'Cmd+K', [Shortcut.OPEN_SETTINGS]: 'Cmd+.', [Shortcut.SHOW_SHORTCUTS]: 'Cmd+/', [Shortcut.TOGGLE_SIDEBAR]: 'Cmd+Shift+S', + [Shortcut.TOGGLE_CONTROLS]: '', [Shortcut.CLOSE_MODAL]: 'Escape', [Shortcut.FOCUS_INPUT]: 'Shift+Escape', [Shortcut.GENERATE_MESSAGE_PAIR]: 'Cmd+Shift+Enter', @@ -225,6 +234,18 @@ export const shortcuts: ShortcutRegistry = { category: 'Chat', configurable: true }, + [Shortcut.NAVIGATE_CHAT_UP]: { + name: 'Navigate to Previous Chat', + keys: [], + category: 'Chat', + configurable: true + }, + [Shortcut.NAVIGATE_CHAT_DOWN]: { + name: 'Navigate to Next Chat', + keys: [], + category: 'Chat', + configurable: true + }, //Global [Shortcut.SEARCH]: { @@ -251,6 +272,12 @@ export const shortcuts: ShortcutRegistry = { category: 'Global', configurable: true }, + [Shortcut.TOGGLE_CONTROLS]: { + name: 'Toggle Controls', + keys: [], + category: 'Global', + configurable: true + }, [Shortcut.CLOSE_MODAL]: { name: 'Close Modal', keys: ['Escape'], diff --git a/src/lib/stores/chatList.ts b/src/lib/stores/chatList.ts index 55b7aa1162..0fbfea960c 100644 --- a/src/lib/stores/chatList.ts +++ b/src/lib/stores/chatList.ts @@ -61,6 +61,27 @@ export const refreshChatList = async ( return { accepted: true, allLoaded }; }; +// The sidebar's folders keep their chat lists in local component state, refreshed +// through a registry of per-folder callbacks that only the sidebar can reach. +// Handlers registered here let other components (e.g. the open chat's menu) +// request that refresh without a reference to the sidebar. +type FolderRefreshHandler = (folderId?: string | null, chat?: ChatListItem | null) => unknown; +const folderRefreshHandlers = new Set(); + +export const registerFolderRefreshHandler = (handler: FolderRefreshHandler) => { + folderRefreshHandlers.add(handler); + return () => { + folderRefreshHandlers.delete(handler); + }; +}; + +export const refreshFolderChatLists = async ( + folderId?: string | null, + chat?: ChatListItem | null +) => { + await Promise.all([...folderRefreshHandlers].map((handler) => handler(folderId, chat))); +}; + export const loadNextChatListPage = async (token: string = ''): Promise => { if (!paginationReady || allLoaded || loadingNextPage) { return { accepted: false, allLoaded }; @@ -105,6 +126,28 @@ export const setChatActive = (chatId: string, active: boolean): boolean => { return found; }; +export const setChatReadAt = (chatId: string, lastReadAt: number): boolean => { + let found = false; + const updateChat = (chat: ChatListItem) => { + if (chat.id !== chatId) { + return chat; + } + found = true; + return { ...chat, last_read_at: lastReadAt }; + }; + + chatsStore.update((items) => (items ? items.map(updateChat) : items)); + pinnedChatsStore.update((items) => items.map(updateChat)); + return found; +}; + +export const setAllChatsRead = () => { + const updateChat = (chat: ChatListItem) => ({ ...chat, last_read_at: chat.updated_at }); + + chatsStore.update((items) => (items ? items.map(updateChat) : items)); + pinnedChatsStore.update((items) => items.map(updateChat)); +}; + export const resetChatListState = () => { requestGeneration += 1; currentPage = 1; diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 0738337035..c213977f32 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -94,7 +94,7 @@ export const adminLeaderboardCount: Writable = writable(null); export const adminFeedbackCount: Writable = writable(null); export const toolServers = writable([]); -export const terminalServers = writable([]); +export const terminalServers: Writable = writable(null); // Persistent Pyodide worker for code interpreter FS export const pyodideWorker: Writable = writable(null); @@ -260,6 +260,8 @@ type Settings = { pinnedMenuItems?: string[]; pinnedNotesOrder?: string[]; + defaultUploadContext?: 'full' | 'focused'; + system?: string; seed?: number; temperature?: string; diff --git a/src/lib/utils/chatId.ts b/src/lib/utils/chatId.ts new file mode 100644 index 0000000000..4772f73a25 --- /dev/null +++ b/src/lib/utils/chatId.ts @@ -0,0 +1,10 @@ +const TEMPORARY_CHAT_ID_PREFIX = 'temporary:'; +const LEGACY_TEMPORARY_CHAT_ID_PREFIX = 'local:'; // Legacy temporary chat prefix. + +export const createTemporaryChatId = (sessionId: string | undefined) => + `${TEMPORARY_CHAT_ID_PREFIX}${sessionId}`; + +export const isTemporaryChatId = (chatId: string | null | undefined) => + !!chatId && + (chatId.startsWith(TEMPORARY_CHAT_ID_PREFIX) || + chatId.startsWith(LEGACY_TEMPORARY_CHAT_ID_PREFIX)); diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index eb23447b03..f4f822b6e6 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -2049,7 +2049,22 @@ export const renderVegaVisualization = async (spec: string, lang: string = '', i const vegaLite = await import('vega-lite'); vegaSpec = vegaLite.compile(parsedSpec).spec; } - const view = new vega.View(vega.parse(vegaSpec), { renderer: 'none' }); + // Specs come from untrusted chat content: block external loads via data.url (loader.load) + // and image mark hrefs emitted into the SVG (loader.sanitize). + const loader = vega.loader(); + loader.load = async () => { + throw new Error('External resource loading is disabled for rendered visualizations'); + }; + const sanitize = loader.sanitize.bind(loader); + loader.sanitize = async (uri: string, options: any) => { + // Resolve with the browser's URL parser so encoding tricks match what it would fetch + const resolved = new URL(uri, document.baseURI); + if (resolved.protocol !== 'data:' && resolved.origin !== location.origin) { + throw new Error('External resource loading is disabled for rendered visualizations'); + } + return sanitize(uri, options); + }; + const view = new vega.View(vega.parse(vegaSpec), { loader, renderer: 'none' }); const svg = await view.toSVG(); return svg; }; diff --git a/src/lib/utils/marked/extension.ts b/src/lib/utils/marked/extension.ts index 13f9f7cdc3..86939c9151 100644 --- a/src/lib/utils/marked/extension.ts +++ b/src/lib/utils/marked/extension.ts @@ -63,6 +63,21 @@ function detailsStart(src: string) { return src.match(/^]/) ? 0 : -1; } +function lheadingTokenizer(this: any, src: string): any { + const cap = this.rules.block.lheading.exec(src); + const detailsIndex = cap?.[1]?.search(/\n]/) ?? -1; + if (!cap || detailsIndex === -1) return false; + + const raw = cap[1].slice(0, detailsIndex + 1); + const text = raw.slice(0, -1); + return { + type: 'paragraph', + raw, + text, + tokens: this.lexer.inline(text) + }; +} + function detailsRenderer(token: any) { const attributesString = token.attributes ? Object.entries(token.attributes) @@ -89,6 +104,9 @@ function detailsExtension() { export default function (options = {}) { return { - extensions: [detailsExtension(options)] + tokenizer: { + lheading: lheadingTokenizer as any + }, + extensions: [detailsExtension()] }; } diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index 62cebf0c96..71bbd80ec7 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -38,7 +38,9 @@ showSearch, showSidebar, showControls, - mobile + mobile, + chatId, + chats } from '$lib/stores'; import Sidebar from '$lib/components/layout/Sidebar.svelte'; @@ -139,51 +141,49 @@ toolServers.set(toolServersData); // Inject enabled terminal servers as always-on tool servers - const enabledTerminals = ($settings?.terminalServers ?? []).filter((s) => s.enabled); - if (enabledTerminals.length > 0) { - let terminalServersData = await getToolServersData( - enabledTerminals.map((t) => ({ - url: t.url, - auth_type: t.auth_type ?? 'bearer', - key: t.key ?? '', - path: t.path ?? '/openapi.json', - config: { enable: true } - })) - ); - terminalServersData = terminalServersData - .filter((data) => { - if (!data || data.error) { - toast.error( - $i18n.t(`Failed to connect to {{URL}} terminal server`, { - URL: data?.url - }) - ); - return false; - } - return true; - }) - .map((data, i) => ({ - ...data, - key: enabledTerminals[i]?.key ?? '' - })); - - terminalServers.set(terminalServersData); - } else { - terminalServers.set([]); - } + const enabledTerminals = (($settings as any)?.terminalServers ?? []).filter( + (s: any) => s.enabled || s.url === $selectedTerminalId + ); // Fetch terminal servers the user has access to (for FileNav + terminal_id) const systemTerminals = await getTerminalServers(localStorage.token); - if (systemTerminals.length > 0) { + terminalServers.set([ + ...(enabledTerminals.length > 0 + ? ( + await getToolServersData( + enabledTerminals.map((t: any) => ({ + url: t.url, + auth_type: t.auth_type ?? 'bearer', + key: t.key ?? '', + path: t.path ?? '/openapi.json', + config: { enable: true } + })) + ) + ) + .filter((data) => { + if (!data || data.error) { + toast.error( + $i18n.t(`Failed to connect to {{URL}} terminal server`, { + URL: data?.url + }) + ); + return false; + } + return true; + }) + .map((data, i) => ({ + ...data, + key: enabledTerminals[i]?.key ?? '' + })) + : []), // Store with proxy URL and session key for FileNav file browsing - const terminalEntries = systemTerminals.map((t) => ({ + ...systemTerminals.map((t) => ({ id: t.id, url: `${WEBUI_API_BASE_URL}/terminals/${t.id}`, name: t.name, key: localStorage.token - })); - terminalServers.update((existing) => [...existing, ...terminalEntries]); - } + })) + ]); }; const setBanners = async () => { @@ -199,6 +199,9 @@ const openSettingsFromUrl = async () => { const requestedSettings = $page.url.searchParams.get('settings'); if (!requestedSettings) { + // Param handled and stripped; allow the same deep link to be + // handled again later in this session. + handledSettingsUrl = ''; return; } @@ -224,9 +227,25 @@ }); }; + const gotoAuth = async () => { + const currentUrl = `${$page.url.pathname}${$page.url.search}`; + await goto(`/auth?redirect=${encodeURIComponent(currentUrl)}`); + }; + + const navigateChat = async (direction: -1 | 1) => { + if (!$chats?.length) return; + + const currentIndex = $chats.findIndex((chat) => chat.id === $chatId); + const nextChat = currentIndex === -1 ? $chats[0] : $chats[currentIndex + direction]; + + if (nextChat) { + await goto(`/c/${nextChat.id}`); + } + }; + onMount(async () => { if ($user === undefined || $user === null) { - await goto('/auth'); + await gotoAuth(); return; } if (!['user', 'admin'].includes($user?.role)) { @@ -243,9 +262,12 @@ }).catch((e) => console.error('Failed to load user settings:', e)) ]); - const loadToolServers = setToolServers().catch((e) => - console.error('Failed to load tool servers:', e) - ); + selectedTerminalId.set(localStorage.selectedTerminalId ?? null); + + const loadToolServers = setToolServers().catch((e) => { + console.error('Failed to load tool servers:', e); + terminalServers.set([]); + }); if ( $page.url.searchParams.get('q') && ($page.url.searchParams.get('submit') ?? 'true') === 'true' @@ -284,6 +306,18 @@ console.log('Shortcut triggered: TOGGLE_SIDEBAR'); event.preventDefault(); showSidebar.set(!$showSidebar); + } else if (shortcut === Shortcut.NAVIGATE_CHAT_UP) { + console.log('Shortcut triggered: NAVIGATE_CHAT_UP'); + event.preventDefault(); + await navigateChat(-1); + } else if (shortcut === Shortcut.NAVIGATE_CHAT_DOWN) { + console.log('Shortcut triggered: NAVIGATE_CHAT_DOWN'); + event.preventDefault(); + await navigateChat(1); + } else if (shortcut === Shortcut.TOGGLE_CONTROLS) { + console.log('Shortcut triggered: TOGGLE_CONTROLS'); + event.preventDefault(); + showControls.set(!$showControls); } else if (shortcut === Shortcut.DELETE_CHAT) { console.log('Shortcut triggered: DELETE_CHAT'); event.preventDefault(); @@ -368,7 +402,6 @@ }); // Persist selectedTerminalId across page loads - selectedTerminalId.set(localStorage.selectedTerminalId ?? null); selectedTerminalId.subscribe((value) => { if (value === null) { delete localStorage.selectedTerminalId; @@ -382,10 +415,17 @@ loaded = true; }); - $: if (loaded) { + // `$page.url` must be referenced here: `$:` only tracks variables used in + // the statement itself, and reads inside openSettingsFromUrl don't count — + // without it, client-side navigations to `?settings=...` are never handled. + $: if (loaded && $page.url) { void openSettingsFromUrl(); } + $: if (loaded && ($user === undefined || $user === null)) { + void gotoAuth(); + } + const checkForVersionUpdates = async () => { version = await getVersionUpdates(localStorage.token).catch((error) => { return { @@ -477,7 +517,9 @@ {#if loaded} - +
+ +
{:else}