fix(a11y): Admin Settings fields are named by their visible labels (#33426)

This commit is contained in:
G30 2026-10-30 16:06:24 -04:00 • committed by GitHub
parent 24c891fabe
commit 0ea4591258
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 561 additions and 99 deletions

View file

@ -377,25 +377,40 @@
placeholder="gpt-realtime-2.1-mini"
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('Voice')}>
<input class={inputClass} bind:value={realtime.VOICE} placeholder="marin" />
<AdminSettingField label={$i18n.t('Voice')} forId="realtime-call-voice">
<input
id="realtime-call-voice"
class={inputClass}
bind:value={realtime.VOICE}
placeholder="marin"
/>
</AdminSettingField>
</div>
<AdminSettingField label={$i18n.t('Input Transcription Model')}>
<input class={inputClass} bind:value={realtime.TRANSCRIPTION_MODEL} />
<AdminSettingField
label={$i18n.t('Input Transcription Model')}
forId="realtime-transcription-model"
>
<input
id="realtime-transcription-model"
class={inputClass}
bind:value={realtime.TRANSCRIPTION_MODEL}
/>
</AdminSettingField>
<AdminSettingField
label={$i18n.t('settings.audio.realtime.inputParams')}
description={$i18n.t('settings.audio.realtime.inputParamsHelp')}
forId="realtime-input-params"
>
<Textarea
id="realtime-input-params"
className={textareaClass}
bind:value={REALTIME_INPUT_PARAMS}
placeholder={$i18n.t('Enter additional parameters in JSON format')}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('Prompt Template')}>
<AdminSettingField label={$i18n.t('Prompt Template')} forId="realtime-prompt-template">
<Textarea
id="realtime-prompt-template"
className={textareaClass}
bind:value={realtime.REALTIME_CALL_PROMPT_TEMPLATE}
placeholder={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
@ -430,8 +445,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.audio.supportedMimeTypes.label')}
description={$i18n.t('settings.admin.audio.supportedMimeTypes.description')}
forId="stt-supported-mime-types"
>
<input
id="stt-supported-mime-types"
class={inputClass}
bind:value={STT_SUPPORTED_CONTENT_TYPES}
placeholder={$i18n.t('e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)')}
@ -441,8 +458,12 @@
{#if STT_ENGINE === 'openai'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.sttOpenaiApiBaseUrl.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttOpenaiApiBaseUrl.label')}
forId="stt-openai-api-base-url"
>
<input
id="stt-openai-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.audio.sttOpenaiApiBaseUrl.label')}
bind:value={STT_OPENAI_API_BASE_URL}
@ -469,8 +490,12 @@
</SettingsSelect>
</AdminSettingRow>
<AdminSettingField label={$i18n.t('settings.admin.audio.sttModel.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttModel.label')}
forId="stt-openai-model"
>
<input
id="stt-openai-model"
list="stt-openai-model-list"
class={inputClass}
bind:value={STT_MODEL}
@ -492,8 +517,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttModel.label')}
description={$i18n.t('settings.admin.audio.sttModel.description')}
forId="stt-deepgram-model"
>
<input
id="stt-deepgram-model"
class={inputClass}
bind:value={STT_MODEL}
placeholder={$i18n.t('Select a model (optional)')}
@ -515,29 +542,45 @@
</AdminSettingField>
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.sttAzureRegion.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttAzureRegion.label')}
forId="stt-azure-region"
>
<input
id="stt-azure-region"
class={inputClass}
bind:value={STT_AZURE_REGION}
placeholder={$i18n.t('e.g., westus (leave blank for eastus)')}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.languageLocales.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.languageLocales.label')}
forId="stt-azure-locales"
>
<input
id="stt-azure-locales"
class={inputClass}
bind:value={STT_AZURE_LOCALES}
placeholder={$i18n.t('e.g., en-US,ja-JP (leave blank for auto-detect)')}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.sttAzureBaseUrl.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttAzureBaseUrl.label')}
forId="stt-azure-base-url"
>
<input
id="stt-azure-base-url"
class={inputClass}
bind:value={STT_AZURE_BASE_URL}
placeholder={$i18n.t('(leave blank for to use commercial endpoint)')}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.maxSpeakers.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.maxSpeakers.label')}
forId="stt-azure-max-speakers"
>
<input
id="stt-azure-max-speakers"
class={inputClass}
bind:value={STT_AZURE_MAX_SPEAKERS}
placeholder={$i18n.t('e.g., 3, 4, 5 (leave blank for default)')}
@ -546,8 +589,12 @@
</div>
{:else if STT_ENGINE === 'mistral'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.sttMistralApiBaseUrl.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttMistralApiBaseUrl.label')}
forId="stt-mistral-api-base-url"
>
<input
id="stt-mistral-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.audio.sttMistralApiBaseUrl.label')}
bind:value={STT_MISTRAL_API_BASE_URL}
@ -566,8 +613,14 @@
<AdminSettingField
label={$i18n.t('settings.admin.audio.mistralSttModel.label')}
description={$i18n.t('settings.admin.audio.mistralSttModel.description')}
forId="stt-mistral-model"
>
<input class={inputClass} bind:value={STT_MODEL} placeholder="voxtral-mini-latest" />
<input
id="stt-mistral-model"
class={inputClass}
bind:value={STT_MODEL}
placeholder="voxtral-mini-latest"
/>
<div class="mt-1 {linkedHelpClass}">
<a href="https://docs.mistral.ai/capabilities/audio_transcription" target="_blank">
{$i18n.t('Learn more about Voxtral transcription.')}
@ -589,9 +642,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.audio.sttWhisperModel.label')}
description={$i18n.t('settings.admin.audio.sttWhisperModel.description')}
forId="stt-whisper-model"
>
<div class="flex w-full gap-2">
<input
id="stt-whisper-model"
class={inputClass}
placeholder={$i18n.t('Set whisper model')}
bind:value={STT_WHISPER_MODEL}
@ -681,8 +736,12 @@
{#if TTS_ENGINE === 'openai' || TTS_ENGINE === 'openai-realtime'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsOpenaiApiBaseUrl.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsOpenaiApiBaseUrl.label')}
forId="tts-openai-api-base-url"
>
<input
id="tts-openai-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.audio.ttsOpenaiApiBaseUrl.label')}
bind:value={TTS_OPENAI_API_BASE_URL}
@ -717,15 +776,23 @@
</AdminSettingField>
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsAzureSpeechRegion.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsAzureSpeechRegion.label')}
forId="tts-azure-speech-region"
>
<input
id="tts-azure-speech-region"
class={inputClass}
bind:value={TTS_AZURE_SPEECH_REGION}
placeholder={$i18n.t('e.g., westus (leave blank for eastus)')}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsAzureSpeechBaseUrl.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsAzureSpeechBaseUrl.label')}
forId="tts-azure-speech-base-url"
>
<input
id="tts-azure-speech-base-url"
class={inputClass}
bind:value={TTS_AZURE_SPEECH_BASE_URL}
placeholder={$i18n.t('(leave blank for to use commercial endpoint)')}
@ -734,8 +801,12 @@
</div>
{:else if TTS_ENGINE === 'mistral'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsMistralApiBaseUrl.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsMistralApiBaseUrl.label')}
forId="tts-mistral-api-base-url"
>
<input
id="tts-mistral-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.audio.ttsMistralApiBaseUrl.label')}
bind:value={TTS_MISTRAL_API_BASE_URL}
@ -772,8 +843,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsModel.label')}
description={$i18n.t('settings.admin.audio.ttsModel.description')}
forId="tts-transformers-model"
>
<input
id="tts-transformers-model"
list="tts-transformers-model-list"
class={inputClass}
bind:value={TTS_MODEL}
@ -795,7 +868,10 @@
</AdminSettingField>
{:else if TTS_ENGINE === 'openai' || TTS_ENGINE === 'openai-realtime'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsVoice.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsVoice.label')}
forId="tts-voice-input"
>
<TTSVoiceInput
bind:value={TTS_VOICE}
voices={providerVoices}
@ -803,8 +879,12 @@
className={inputClass}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsModel.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsModel.label')}
forId="tts-openai-model"
>
<input
id="tts-openai-model"
list="tts-model-list"
class={inputClass}
bind:value={TTS_MODEL}
@ -816,16 +896,22 @@
<AdminSettingField
label={$i18n.t('settings.admin.audio.additionalParameters.label')}
description={$i18n.t('settings.admin.audio.additionalParameters.description')}
forId="tts-openai-params"
>
<Textarea
id="tts-openai-params"
className={textareaClass}
bind:value={TTS_OPENAI_PARAMS}
placeholder={$i18n.t('Enter additional parameters in JSON format')}
/>
</AdminSettingField>
{:else}
<AdminSettingField label={$i18n.t('Prompt Template')}>
<AdminSettingField
label={$i18n.t('Prompt Template')}
forId="realtime-tts-prompt-template"
>
<Textarea
id="realtime-tts-prompt-template"
className={textareaClass}
bind:value={REALTIME_TTS_PROMPT_TEMPLATE}
placeholder={$i18n.t(
@ -836,7 +922,10 @@
{/if}
{:else if TTS_ENGINE === 'elevenlabs' || TTS_ENGINE === 'mistral'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsVoice.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsVoice.label')}
forId="tts-voice-input"
>
<TTSVoiceInput
bind:value={TTS_VOICE}
voices={providerVoices}
@ -844,8 +933,12 @@
className={inputClass}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsModel.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsModel.label')}
forId="tts-elevenlabs-mistral-model"
>
<input
id="tts-elevenlabs-mistral-model"
list="tts-model-list"
class={inputClass}
bind:value={TTS_MODEL}
@ -855,7 +948,10 @@
</div>
{:else if TTS_ENGINE === 'azure'}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsVoice.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.ttsVoice.label')}
forId="tts-voice-input"
>
<TTSVoiceInput
bind:value={TTS_VOICE}
voices={providerVoices}
@ -863,8 +959,12 @@
className={inputClass}
/>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.audio.outputFormat.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.audio.outputFormat.label')}
forId="tts-azure-speech-output-format"
>
<input
id="tts-azure-speech-output-format"
class={inputClass}
bind:value={TTS_AZURE_SPEECH_OUTPUT_FORMAT}
placeholder={$i18n.t('Select an output format')}

View file

@ -226,8 +226,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.allowedEndpoints.label')}
description={$i18n.t('settings.admin.authentication.allowedEndpoints.description')}
forId="api-keys-allowed-endpoints"
>
<input
id="api-keys-allowed-endpoints"
class={inputClass}
type="text"
placeholder={`e.g.) /api/v1/messages, /api/v1/channels`}
@ -247,8 +249,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.jwtExpiration.label')}
description={$i18n.t('settings.admin.authentication.jwtExpiration.description')}
forId="jwt-expiration"
>
<input
id="jwt-expiration"
class={inputClass}
type="text"
placeholder={`e.g.) "30m","1h", "10d". `}
@ -315,8 +319,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.adminContactEmail.label')}
description={$i18n.t('settings.admin.authentication.adminContactEmail.description')}
forId="admin-contact-email"
>
<input
id="admin-contact-email"
class={inputClass}
type="email"
placeholder={$i18n.t('Leave empty to use first admin user')}
@ -369,8 +375,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.label.label')}
description={$i18n.t('settings.admin.authentication.label.description')}
forId="ldap-label"
>
<input
id="ldap-label"
class={inputClass}
required
placeholder={$i18n.t('Enter server label')}
@ -383,8 +391,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.host.label')}
description={$i18n.t('settings.admin.authentication.host.description')}
forId="ldap-host"
>
<input
id="ldap-host"
class={inputClass}
required
placeholder={$i18n.t('Enter server host')}
@ -395,6 +405,7 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.port.label')}
description={$i18n.t('settings.admin.authentication.port.description')}
forId="ldap-port"
>
<Tooltip
placement="top-start"
@ -402,6 +413,7 @@
className="w-full"
>
<input
id="ldap-port"
class={inputClass}
type="number"
placeholder={$i18n.t('Enter server port')}
@ -415,12 +427,14 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.applicationDn.label')}
description={$i18n.t('settings.admin.authentication.applicationDn.description')}
forId="ldap-application-dn"
>
<Tooltip
content={$i18n.t('The Application Account DN you bind with for search')}
placement="top-start"
>
<input
id="ldap-application-dn"
class={inputClass}
placeholder={$i18n.t('Enter Application DN')}
bind:value={LDAP_SERVER.app_dn}
@ -445,6 +459,7 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.attributeForMail.label')}
description={$i18n.t('settings.admin.authentication.attributeForMail.description')}
forId="ldap-attribute-for-mail"
>
<Tooltip
content={$i18n.t(
@ -453,6 +468,7 @@
placement="top-start"
>
<input
id="ldap-attribute-for-mail"
class={inputClass}
required
placeholder={$i18n.t('Example: mail')}
@ -464,6 +480,7 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.attributeForUsername.label')}
description={$i18n.t('settings.admin.authentication.attributeForUsername.description')}
forId="ldap-attribute-for-username"
>
<Tooltip
content={$i18n.t(
@ -472,6 +489,7 @@
placement="top-start"
>
<input
id="ldap-attribute-for-username"
class={inputClass}
required
placeholder={$i18n.t('Example: sAMAccountName or uid or userPrincipalName')}
@ -484,8 +502,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.defaultEmailDomain.label')}
description={$i18n.t('settings.admin.authentication.defaultEmailDomain.description')}
forId="ldap-default-email-domain"
>
<input
id="ldap-default-email-domain"
class={inputClass}
placeholder="example.com"
bind:value={LDAP_SERVER.default_email_domain}
@ -495,9 +515,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.searchBase.label')}
description={$i18n.t('settings.admin.authentication.searchBase.description')}
forId="ldap-search-base"
>
<Tooltip content={$i18n.t('The base to search for users')} placement="top-start">
<input
id="ldap-search-base"
class={inputClass}
required
placeholder={$i18n.t('Example: ou=users,dc=foo,dc=example')}
@ -509,8 +531,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.searchFilters.label')}
description={$i18n.t('settings.admin.authentication.searchFilters.description')}
forId="ldap-search-filters"
>
<input
id="ldap-search-filters"
class={inputClass}
placeholder={$i18n.t('Example: (&(objectClass=inetOrgPerson)(uid=%s))')}
bind:value={LDAP_SERVER.search_filters}
@ -536,8 +560,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.certificatePath.label')}
description={$i18n.t('settings.admin.authentication.certificatePath.description')}
forId="ldap-certificate-path"
>
<input
id="ldap-certificate-path"
class={inputClass}
placeholder={$i18n.t('Enter certificate path')}
bind:value={LDAP_SERVER.certificate_path}
@ -555,9 +581,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.ciphers.label')}
description={$i18n.t('settings.admin.authentication.ciphers.description')}
forId="ldap-ciphers"
>
<Tooltip content={$i18n.t('Default to ALL')} placement="top-start">
<input
id="ldap-ciphers"
class={inputClass}
placeholder={$i18n.t('Example: ALL')}
bind:value={LDAP_SERVER.ciphers}
@ -589,9 +617,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.groupAttribute.label')}
description={$i18n.t('settings.admin.authentication.groupAttribute.description')}
forId="ldap-group-attribute"
>
<Tooltip content={$i18n.t('Default to memberOf')} placement="top-start">
<input
id="ldap-group-attribute"
class={inputClass}
placeholder="memberOf"
bind:value={LDAP_SERVER.attribute_for_groups}
@ -634,8 +664,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.providerName.label')}
description={$i18n.t('settings.admin.authentication.providerName.description')}
forId="oauth-provider-name"
>
<input
id="oauth-provider-name"
class={inputClass}
placeholder="SSO"
bind:value={oauthConfig.OAUTH_PROVIDER_NAME}
@ -645,8 +677,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.providerUrl.label')}
description={$i18n.t('settings.admin.authentication.providerUrl.description')}
forId="oauth-provider-url"
>
<input
id="oauth-provider-url"
class={inputClass}
placeholder="https://accounts.google.com/.well-known/openid-configuration"
bind:value={oauthConfig.OPENID_PROVIDER_URL}
@ -658,8 +692,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.clientId.label')}
description={$i18n.t('settings.admin.authentication.clientId.description')}
forId="oauth-client-id"
>
<input
id="oauth-client-id"
class={inputClass}
placeholder={$i18n.t('Enter Client ID')}
bind:value={oauthConfig.OAUTH_CLIENT_ID}
@ -683,8 +719,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.redirectUri.label')}
description={$i18n.t('settings.admin.authentication.redirectUri.description')}
forId="oauth-redirect-uri"
>
<input
id="oauth-redirect-uri"
class={inputClass}
placeholder={$i18n.t('Enter Redirect URI')}
bind:value={oauthConfig.OPENID_REDIRECT_URI}
@ -694,8 +732,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.scopes.label')}
description={$i18n.t('settings.admin.authentication.scopes.description')}
forId="oauth-scopes"
>
<input
id="oauth-scopes"
class={inputClass}
placeholder="openid email profile"
bind:value={oauthConfig.OAUTH_SCOPES}
@ -707,8 +747,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.emailClaim.label')}
description={$i18n.t('settings.admin.authentication.emailClaim.description')}
forId="oauth-email-claim"
>
<input
id="oauth-email-claim"
class={inputClass}
placeholder="email"
bind:value={oauthConfig.OAUTH_EMAIL_CLAIM}
@ -718,8 +760,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.usernameClaim.label')}
description={$i18n.t('settings.admin.authentication.usernameClaim.description')}
forId="oauth-username-claim"
>
<input
id="oauth-username-claim"
class={inputClass}
placeholder="name"
bind:value={oauthConfig.OAUTH_USERNAME_CLAIM}
@ -731,8 +775,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.pictureClaim.label')}
description={$i18n.t('settings.admin.authentication.pictureClaim.description')}
forId="oauth-picture-claim"
>
<input
id="oauth-picture-claim"
class={inputClass}
placeholder="picture"
bind:value={oauthConfig.OAUTH_PICTURE_CLAIM}
@ -742,8 +788,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.subClaim.label')}
description={$i18n.t('settings.admin.authentication.subClaim.description')}
forId="oauth-sub-claim"
>
<input
id="oauth-sub-claim"
class={inputClass}
placeholder="sub"
bind:value={oauthConfig.OAUTH_SUB_CLAIM}
@ -783,8 +831,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.allowedDomains.label')}
description={$i18n.t('settings.admin.authentication.allowedDomains.description')}
forId="oauth-allowed-domains"
>
<input
id="oauth-allowed-domains"
class={inputClass}
placeholder={$i18n.t('* (all domains)')}
bind:value={oauthConfig.OAUTH_ALLOWED_DOMAINS}
@ -810,8 +860,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.rolesClaim.label')}
description={$i18n.t('settings.admin.authentication.rolesClaim.description')}
forId="oauth-roles-claim"
>
<input
id="oauth-roles-claim"
class={inputClass}
placeholder="roles"
bind:value={oauthConfig.OAUTH_ROLES_CLAIM}
@ -821,8 +873,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.adminRoles.label')}
description={$i18n.t('settings.admin.authentication.adminRoles.description')}
forId="oauth-admin-roles"
>
<input
id="oauth-admin-roles"
class={inputClass}
placeholder="admin"
bind:value={oauthConfig.OAUTH_ADMIN_ROLES}
@ -833,8 +887,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.allowedRoles.label')}
description={$i18n.t('settings.admin.authentication.allowedRoles.description')}
forId="oauth-allowed-roles"
>
<input
id="oauth-allowed-roles"
class={inputClass}
placeholder="*"
bind:value={oauthConfig.OAUTH_ALLOWED_ROLES}
@ -876,8 +932,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.groupClaim.label')}
description={$i18n.t('settings.admin.authentication.groupClaim.description')}
forId="oauth-group-claim"
>
<input
id="oauth-group-claim"
class={inputClass}
placeholder="groups"
bind:value={oauthConfig.OAUTH_GROUP_CLAIM}
@ -887,8 +945,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.authentication.blockedGroups.label')}
description={$i18n.t('settings.admin.authentication.blockedGroups.description')}
forId="oauth-blocked-groups"
>
<input
id="oauth-blocked-groups"
class={inputClass}
placeholder={$i18n.t('Comma-separated group names')}
bind:value={oauthConfig.OAUTH_BLOCKED_GROUPS}

View file

@ -90,8 +90,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeExecutionJupyterUrl.description'
)}
forId="code-execution-jupyter-url"
>
<input
id="code-execution-jupyter-url"
class={inputClass}
type="text"
placeholder={$i18n.t('Enter Jupyter URL')}
@ -155,8 +157,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeExecutionJupyterTimeout.description'
)}
forId="code-execution-jupyter-timeout"
>
<input
id="code-execution-jupyter-timeout"
class={inputClass}
type="number"
bind:value={config.CODE_EXECUTION_JUPYTER_TIMEOUT}
@ -208,8 +212,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeInterpreterJupyterUrl.description'
)}
forId="code-interpreter-jupyter-url"
>
<input
id="code-interpreter-jupyter-url"
class={inputClass}
type="text"
placeholder={$i18n.t('Enter Jupyter URL')}
@ -273,8 +279,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeInterpreterJupyterTimeout.description'
)}
forId="code-interpreter-jupyter-timeout"
>
<input
id="code-interpreter-jupyter-timeout"
class={inputClass}
type="number"
bind:value={config.CODE_INTERPRETER_JUPYTER_TIMEOUT}
@ -289,8 +297,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeInterpreterPromptTemplate.description'
)}
forId="code-interpreter-prompt-template"
>
<Textarea
id="code-interpreter-prompt-template"
className={textareaClass}
bind:value={config.CODE_INTERPRETER_PROMPT_TEMPLATE}
placeholder={$i18n.t(

View file

@ -62,6 +62,7 @@
<input
class="text-gray-600 dark:text-gray-400 transition-colors duration-150 group-hover/setting-row:text-gray-900 group-focus-within/setting-row:text-gray-900 dark:group-hover/setting-row:text-white dark:group-focus-within/setting-row:text-white w-full text-sm bg-transparent outline-hidden"
placeholder={$i18n.t('Enter URL (e.g. http://localhost:11434)')}
aria-label={$i18n.t('URL')}
bind:value={url}
readonly={true}
/>

View file

@ -62,6 +62,7 @@
? 'pr-8'
: ''}"
placeholder={$i18n.t('API Base URL')}
aria-label={$i18n.t('API Base URL')}
bind:value={url}
autocomplete="off"
readonly={true}

View file

@ -497,8 +497,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.supportedMediaMimeTypes.label')}
description={$i18n.t('settings.admin.documents.supportedMediaMimeTypes.description')}
forId="supported-media-mime-types"
>
<input
id="supported-media-mime-types"
class={inputClass}
placeholder={$i18n.t('image/*, video/*')}
bind:value={RAGConfig.CONTENT_EXTRACTION_SUPPORTED_MEDIA_MIME_TYPES}
@ -528,8 +530,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.datalabMarkerApiBaseUrl.label')}
description={$i18n.t('settings.admin.documents.datalabMarkerApiBaseUrl.description')}
forId="datalab-marker-api-base-url"
>
<input
id="datalab-marker-api-base-url"
class={inputClass}
placeholder={$i18n.t('Enter Datalab Marker API Base URL')}
bind:value={RAGConfig.DATALAB_MARKER_API_BASE_URL}
@ -551,6 +555,7 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.additionalConfig.label')}
description={$i18n.t('settings.admin.documents.additionalConfig.description')}
forId="datalab-marker-additional-config"
>
<Tooltip
content={$i18n.t(
@ -560,6 +565,7 @@
className="w-full"
>
<Textarea
id="datalab-marker-additional-config"
className={textareaClass}
bind:value={RAGConfig.DATALAB_MARKER_ADDITIONAL_CONFIG}
placeholder={$i18n.t('Enter JSON config (e.g., {"disable_links": true})')}
@ -641,8 +647,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.documentLoaderUrl.label')}
description={$i18n.t('settings.admin.documents.documentLoaderUrl.description')}
forId="external-document-loader-url"
>
<input
id="external-document-loader-url"
class={inputClass}
placeholder={$i18n.t('Enter External Document Loader URL')}
bind:value={RAGConfig.EXTERNAL_DOCUMENT_LOADER_URL}
@ -666,6 +674,7 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.headers.label')}
description={$i18n.t('settings.admin.documents.headers.description')}
forId="external-document-loader-headers"
>
<Tooltip
content={$i18n.t(
@ -673,6 +682,7 @@
)}
>
<Textarea
id="external-document-loader-headers"
className={textareaClass}
bind:value={RAGConfig.EXTERNAL_DOCUMENT_LOADER_HEADERS}
placeholder={$i18n.t('Enter additional headers in JSON format')}
@ -710,8 +720,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.tikaServerUrl.label')}
description={$i18n.t('settings.admin.documents.tikaServerUrl.description')}
forId="tika-server-url"
>
<input
id="tika-server-url"
class={inputClass}
placeholder={$i18n.t('Enter Tika Server URL')}
bind:value={RAGConfig.TIKA_SERVER_URL}
@ -720,8 +732,9 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.tikaServerVersion.label')}
description={$i18n.t('settings.admin.documents.tikaServerVersion.description')}
forId="tika-server-version"
>
<SettingsSelect bind:value={RAGConfig.TIKA_SERVER_VERSION}>
<SettingsSelect id="tika-server-version" bind:value={RAGConfig.TIKA_SERVER_VERSION}>
<option value="3">{$i18n.t('Tika 3.x')}</option>
<option value="4">{$i18n.t('Tika 4.x')}</option>
</SettingsSelect>
@ -732,8 +745,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.doclingServerUrl.label')}
description={$i18n.t('settings.admin.documents.doclingServerUrl.description')}
forId="docling-server-url"
>
<input
id="docling-server-url"
class={inputClass}
placeholder={$i18n.t('Enter Docling Server URL')}
bind:value={RAGConfig.DOCLING_SERVER_URL}
@ -755,8 +770,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.doclingParams.label')}
description={$i18n.t('settings.admin.documents.doclingParams.description')}
forId="docling-params"
>
<Textarea
id="docling-params"
className={textareaClass}
bind:value={RAGConfig.DOCLING_PARAMS}
placeholder={$i18n.t('Enter additional parameters in JSON format')}
@ -768,8 +785,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.endpoint.label')}
description={$i18n.t('settings.admin.documents.endpoint.description')}
forId="document-intelligence-endpoint"
>
<input
id="document-intelligence-endpoint"
class={inputClass}
placeholder={$i18n.t('Enter Document Intelligence Endpoint')}
bind:value={RAGConfig.DOCUMENT_INTELLIGENCE_ENDPOINT}
@ -791,8 +810,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.documentIntelligenceModel.label')}
description={$i18n.t('settings.admin.documents.documentIntelligenceModel.description')}
forId="document-intelligence-model"
>
<input
id="document-intelligence-model"
class={inputClass}
placeholder={$i18n.t('Enter Document Intelligence Model')}
bind:value={RAGConfig.DOCUMENT_INTELLIGENCE_MODEL}
@ -803,8 +824,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.mistralOcrApiBaseUrl.label')}
description={$i18n.t('settings.admin.documents.mistralOcrApiBaseUrl.description')}
forId="mistral-ocr-api-base-url"
>
<input
id="mistral-ocr-api-base-url"
class={inputClass}
placeholder={$i18n.t('Enter Mistral API Base URL')}
bind:value={RAGConfig.MISTRAL_OCR_API_BASE_URL}
@ -831,8 +854,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.mistralOcrParams.label')}
description={$i18n.t('settings.admin.documents.mistralOcrParams.description')}
forId="mistral-ocr-params"
>
<Textarea
id="mistral-ocr-params"
className={textareaClass}
bind:value={RAGConfig.MISTRAL_OCR_PARAMS}
placeholder={$i18n.t('Enter additional parameters in JSON format')}
@ -844,8 +869,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.paddleocrVlBaseUrl.label')}
description={$i18n.t('settings.admin.documents.paddleocrVlBaseUrl.description')}
forId="paddleocr-vl-base-url"
>
<input
id="paddleocr-vl-base-url"
class={inputClass}
placeholder={$i18n.t('Enter PaddleOCR-vl API Base URL')}
bind:value={RAGConfig.PADDLEOCR_VL_BASE_URL}
@ -895,8 +922,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.apiUrl.label')}
description={$i18n.t('settings.admin.documents.apiUrl.description')}
forId="mineru-api-url"
>
<input
id="mineru-api-url"
class={inputClass}
placeholder={RAGConfig.MINERU_API_MODE === 'cloud'
? $i18n.t('https://mineru.net/api/v4')
@ -935,8 +964,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.mineruParams.label')}
description={$i18n.t('settings.admin.documents.mineruParams.description')}
forId="mineru-params"
>
<Textarea
id="mineru-params"
className={textareaClass}
bind:value={RAGConfig.MINERU_PARAMS}
placeholder={`{\n "enable_ocr": false,\n "enable_formula": true,\n "enable_table": true,\n "language": "en",\n "model_version": "pipeline",\n "page_ranges": ""\n}`}
@ -947,8 +978,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.fileExtensions.label')}
description={$i18n.t('settings.admin.documents.fileExtensions.description')}
forId="mineru-file-extensions"
>
<input
id="mineru-file-extensions"
class={inputClass}
placeholder={$i18n.t('pdf, docx, pptx, xlsx')}
bind:value={RAGConfig.MINERU_FILE_EXTENSIONS}
@ -988,8 +1021,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.tokenizerModel.label')}
description={$i18n.t('settings.admin.documents.tokenizerModel.description')}
forId="tokenizer-model"
>
<input
id="tokenizer-model"
class={inputClass}
placeholder={$i18n.t('Enter Tokenizer Model')}
bind:value={RAGConfig.RAG_TOKENIZER_MODEL}
@ -1014,8 +1049,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.chunkSize.label')}
description={$i18n.t('settings.admin.documents.chunkSize.description')}
forId="chunk-size"
>
<input
id="chunk-size"
class={inputClass}
type="number"
placeholder={$i18n.t('Enter Chunk Size')}
@ -1027,8 +1064,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.chunkOverlap.label')}
description={$i18n.t('settings.admin.documents.chunkOverlap.description')}
forId="chunk-overlap"
>
<input
id="chunk-overlap"
class={inputClass}
type="number"
placeholder={$i18n.t('Enter Chunk Overlap')}
@ -1043,8 +1082,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.chunkMinSizeTarget.label')}
description={$i18n.t('settings.admin.documents.chunkMinSizeTarget.description')}
forId="chunk-min-size-target"
>
<input
id="chunk-min-size-target"
class={inputClass}
type="number"
placeholder={$i18n.t('Enter Chunk Min Size Target')}
@ -1094,8 +1135,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.openaiurl.label')}
description={$i18n.t('settings.admin.documents.openaiurl.description')}
forId="embedding-openai-url"
>
<input
id="embedding-openai-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.documents.openaiurl.label')}
bind:value={OpenAIUrl}
@ -1119,8 +1162,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.ollamaurl.label')}
description={$i18n.t('settings.admin.documents.ollamaurl.description')}
forId="embedding-ollama-url"
>
<input
id="embedding-ollama-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.documents.ollamaurl.label')}
bind:value={OllamaUrl}
@ -1144,8 +1189,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.azureopenaiurl.label')}
description={$i18n.t('settings.admin.documents.azureopenaiurl.description')}
forId="embedding-azure-openai-url"
>
<input
id="embedding-azure-openai-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.documents.azureopenaiurl.label')}
bind:value={AzureOpenAIUrl}
@ -1165,8 +1212,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.version.label')}
description={$i18n.t('settings.admin.documents.version.description')}
forId="embedding-azure-openai-version"
>
<input
id="embedding-azure-openai-version"
class={inputClass}
placeholder={$i18n.t('settings.admin.documents.version.label')}
bind:value={AzureOpenAIVersion}
@ -1179,9 +1228,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.embeddingModel.label')}
description={$i18n.t('settings.admin.documents.embeddingModel.description')}
forId="embedding-model"
>
<div class="flex w-full gap-2">
<input
id="embedding-model"
class={inputClass}
placeholder={RAG_EMBEDDING_ENGINE === 'ollama'
? $i18n.t('Set embedding model')
@ -1371,8 +1422,10 @@
description={$i18n.t(
'settings.admin.documents.ragExternalRerankerUrl.description'
)}
forId="external-reranker-url"
>
<input
id="external-reranker-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.documents.ragExternalRerankerUrl.label')}
bind:value={RAGConfig.RAG_EXTERNAL_RERANKER_URL}
@ -1400,8 +1453,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.rerankingModel.label')}
description={$i18n.t('settings.admin.documents.rerankingModel.description')}
forId="reranking-model"
>
<input
id="reranking-model"
class={inputClass}
placeholder={$i18n.t('Set reranking model (e.g. {{model}})', {
model: 'BAAI/bge-reranker-v2-m3'
@ -1430,8 +1485,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.topK.label')}
description={$i18n.t('settings.admin.documents.topK.description')}
forId="top-k"
>
<input
id="top-k"
class={inputClass}
type="number"
placeholder={$i18n.t('Enter Top K')}
@ -1445,8 +1502,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.topKReranker.label')}
description={$i18n.t('settings.admin.documents.topKReranker.description')}
forId="top-k-reranker"
>
<input
id="top-k-reranker"
class={inputClass}
type="number"
placeholder={$i18n.t('Enter Top K Reranker')}
@ -1459,8 +1518,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.relevanceThreshold.label')}
description={$i18n.t('settings.admin.documents.relevanceThreshold.description')}
forId="relevance-threshold"
>
<input
id="relevance-threshold"
class={inputClass}
type="number"
step="0.01"
@ -1495,6 +1556,7 @@
<div class="flex-1">
<input
id="steps-range"
aria-label={$i18n.t('settings.admin.documents.bm25Weight.label')}
type="range"
min="0"
max="1"
@ -1511,6 +1573,7 @@
</div>
<input
bind:value={RAGConfig.HYBRID_BM25_WEIGHT}
aria-label={$i18n.t('settings.admin.documents.bm25Weight.label')}
type="number"
class="w-14 bg-transparent text-center text-xs outline-none"
min="0"
@ -1526,6 +1589,7 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.ragTemplate.label')}
description={$i18n.t('settings.admin.documents.ragTemplate.description')}
forId="rag-template"
>
<Tooltip
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
@ -1533,6 +1597,7 @@
className="w-full"
>
<Textarea
id="rag-template"
className={textareaClass}
bind:value={RAGConfig.RAG_TEMPLATE}
placeholder={$i18n.t(
@ -1555,8 +1620,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.allowedFileExtensions.label')}
description={$i18n.t('settings.admin.documents.allowedFileExtensions.description')}
forId="allowed-file-extensions"
>
<input
id="allowed-file-extensions"
class={inputClass}
type="text"
placeholder={$i18n.t('e.g. pdf, docx, txt')}
@ -1569,8 +1636,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.maxUploadSize.label')}
description={$i18n.t('settings.admin.documents.maxUploadSize.description')}
forId="max-upload-size"
>
<input
id="max-upload-size"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
@ -1582,8 +1651,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.maxUploadCount.label')}
description={$i18n.t('settings.admin.documents.maxUploadCount.description')}
forId="max-upload-count"
>
<input
id="max-upload-count"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
@ -1597,8 +1668,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.knowledgeMaxUploadCount.label')}
description={$i18n.t('settings.admin.documents.knowledgeMaxUploadCount.description')}
forId="knowledge-max-upload-count"
>
<input
id="knowledge-max-upload-count"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
@ -1613,8 +1686,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.knowledgeMaxSize.label')}
description={$i18n.t('settings.admin.documents.knowledgeMaxSize.description')}
forId="knowledge-max-upload-file-size"
>
<input
id="knowledge-max-upload-file-size"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
@ -1627,8 +1702,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.knowledgeMaxCount.label')}
description={$i18n.t('settings.admin.documents.knowledgeMaxCount.description')}
forId="knowledge-max-upload-file-count"
>
<input
id="knowledge-max-upload-file-count"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
@ -1644,8 +1721,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.imageCompressionWidth.label')}
description={$i18n.t('settings.admin.documents.imageCompressionWidth.description')}
forId="image-compression-width"
>
<input
id="image-compression-width"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for no compression')}
@ -1657,8 +1736,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.documents.imageCompressionHeight.label')}
description={$i18n.t('settings.admin.documents.imageCompressionHeight.description')}
forId="image-compression-height"
>
<input
id="image-compression-height"
class={inputClass}
type="number"
placeholder={$i18n.t('Leave empty for no compression')}

View file

@ -308,8 +308,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.general.folderMaxFileCount.label')}
description={$i18n.t('settings.admin.general.folderMaxFileCount.description')}
forId="folder-max-file-count"
>
<input
id="folder-max-file-count"
class={inputClass}
type="number"
min="0"
@ -471,8 +473,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.general.webuiUrl.label')}
description={$i18n.t('settings.admin.general.webuiUrl.description')}
forId="webui-url"
>
<input
id="webui-url"
class={inputClass}
type="text"
placeholder={`e.g.) "http://localhost:3000"`}

View file

@ -358,8 +358,10 @@
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField
label={$i18n.t('settings.admin.images.imageGenerationModel.label')}
forId="image-generation-model"
>
<input
id="image-generation-model"
list="model-list"
class={inputClass}
bind:value={config.IMAGE_GENERATION_MODEL}
@ -374,8 +376,12 @@
</datalist>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.images.imageSize.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.images.imageSize.label')}
forId="image-size"
>
<input
id="image-size"
class={inputClass}
placeholder={$i18n.t('Enter Image Size (e.g. 512x512)')}
bind:value={config.IMAGE_SIZE}
@ -383,8 +389,12 @@
</AdminSettingField>
{#if ['comfyui', 'automatic1111', ''].includes(config?.IMAGE_GENERATION_ENGINE)}
<AdminSettingField label={$i18n.t('settings.admin.images.steps.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.images.steps.label')}
forId="image-steps"
>
<input
id="image-steps"
class={inputClass}
placeholder={$i18n.t('Enter Number of Steps (e.g. 50)')}
bind:value={config.IMAGE_STEPS}
@ -409,8 +419,10 @@
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesOpenaiApiBaseUrl.label')}
forId="images-openai-api-base-url"
>
<input
id="images-openai-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.images.imagesOpenaiApiBaseUrl.label')}
bind:value={config.IMAGES_OPENAI_API_BASE_URL}
@ -431,8 +443,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesOpenaiApiVersion.label')}
forId="images-openai-api-version"
>
<input
id="images-openai-api-version"
class={inputClass}
placeholder={$i18n.t('settings.admin.images.imagesOpenaiApiVersion.label')}
bind:value={config.IMAGES_OPENAI_API_VERSION}
@ -442,8 +456,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesOpenaiApiParams.label')}
description={$i18n.t('settings.admin.images.imagesOpenaiApiParams.description')}
forId="images-openai-api-params"
>
<Textarea
id="images-openai-api-params"
className={textareaClass}
bind:value={config.IMAGES_OPENAI_API_PARAMS}
placeholder={$i18n.t('Enter additional parameters in JSON format')}
@ -454,9 +470,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.automatic1111BaseUrl.label')}
description={$i18n.t('settings.admin.images.automatic1111BaseUrl.description')}
forId="automatic1111-base-url"
>
<div class="flex w-full gap-2">
<input
id="automatic1111-base-url"
class={inputClass}
placeholder={$i18n.t('Enter URL (e.g. http://127.0.0.1:7860/)')}
bind:value={config.AUTOMATIC1111_BASE_URL}
@ -513,8 +531,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.automatic1111Params.label')}
description={$i18n.t('settings.admin.images.automatic1111Params.description')}
forId="automatic1111-params"
>
<Textarea
id="automatic1111-params"
className={textareaClass}
bind:value={config.AUTOMATIC1111_PARAMS}
placeholder={$i18n.t('Enter additional parameters in JSON format')}
@ -525,9 +545,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.comfyuiBaseUrl.label')}
description={$i18n.t('settings.admin.images.comfyuiBaseUrl.description')}
forId="comfyui-base-url"
>
<div class="flex w-full gap-2">
<input
id="comfyui-base-url"
class={inputClass}
placeholder={$i18n.t('Enter URL (e.g. http://127.0.0.1:7860/)')}
bind:value={config.COMFYUI_BASE_URL}
@ -671,17 +693,19 @@
{#each REQUIRED_WORKFLOW_NODES as node}
<div class="flex w-full flex-col">
<div class="shrink-0">
<div
<label
for={`comfyui-workflow-node-${node.type}-key`}
class=" capitalize line-clamp-1 w-20 text-gray-400 dark:text-gray-500"
>
{node.type}{node.type === 'prompt' ? '*' : ''}
</div>
</label>
</div>
<div class="flex mt-0.5 items-center">
<div class="">
<Tooltip content={$i18n.t('Input Key (e.g. text, unet_name, steps)')}>
<input
id={`comfyui-workflow-node-${node.type}-key`}
class="{inputClass} w-24"
placeholder={$i18n.t('Key')}
bind:value={node.key}
@ -700,6 +724,7 @@
<input
class={inputClass}
placeholder={$i18n.t('Node Ids')}
aria-label={$i18n.t('Node Ids')}
bind:value={node.node_ids}
/>
</Tooltip>
@ -718,8 +743,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesGeminiApiBaseUrl.label')}
description={$i18n.t('settings.admin.images.imagesGeminiApiBaseUrl.description')}
forId="images-gemini-api-base-url"
>
<input
id="images-gemini-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.images.imagesOpenaiApiBaseUrl.label')}
bind:value={config.IMAGES_GEMINI_API_BASE_URL}
@ -782,8 +809,12 @@
{#if config?.ENABLE_IMAGE_EDIT}
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.images.imageEditModel.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.images.imageEditModel.label')}
forId="image-edit-model"
>
<input
id="image-edit-model"
list="model-list"
class={inputClass}
bind:value={config.IMAGE_EDIT_MODEL}
@ -797,8 +828,12 @@
</datalist>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.images.imageEditSize.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.images.imageEditSize.label')}
forId="image-edit-size"
>
<input
id="image-edit-size"
class={inputClass}
placeholder={$i18n.t('Enter Image Size (e.g. 512x512)')}
bind:value={config.IMAGE_EDIT_SIZE}
@ -811,8 +846,10 @@
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesEditOpenaiApiBaseUrl.label')}
forId="images-edit-openai-api-base-url"
>
<input
id="images-edit-openai-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.images.imagesEditOpenaiApiBaseUrl.label')}
bind:value={config.IMAGES_EDIT_OPENAI_API_BASE_URL}
@ -833,8 +870,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesEditOpenaiApiVersion.label')}
forId="images-edit-openai-api-version"
>
<input
id="images-edit-openai-api-version"
class={inputClass}
placeholder={$i18n.t('settings.admin.images.imagesEditOpenaiApiVersion.label')}
bind:value={config.IMAGES_EDIT_OPENAI_API_VERSION}
@ -844,9 +883,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesEditComfyuiBaseUrl.label')}
description={$i18n.t('settings.admin.images.imagesEditComfyuiBaseUrl.description')}
forId="images-edit-comfyui-base-url"
>
<div class="flex w-full gap-2">
<input
id="images-edit-comfyui-base-url"
class={inputClass}
placeholder={$i18n.t('Enter URL (e.g. http://127.0.0.1:7860/)')}
bind:value={config.IMAGES_EDIT_COMFYUI_BASE_URL}
@ -980,17 +1021,19 @@
{#each REQUIRED_EDIT_WORKFLOW_NODES as node}
<div class="flex w-full flex-col">
<div class="shrink-0">
<div
<label
for={`comfyui-edit-workflow-node-${node.type}-key`}
class=" capitalize line-clamp-1 w-20 text-gray-400 dark:text-gray-500"
>
{node.type}{['prompt', 'image'].includes(node.type) ? '*' : ''}
</div>
</label>
</div>
<div class="flex mt-0.5 items-center">
<div class="">
<Tooltip content={$i18n.t('Input Key (e.g. text, unet_name, steps)')}>
<input
id={`comfyui-edit-workflow-node-${node.type}-key`}
class="{inputClass} w-24"
placeholder={$i18n.t('Key')}
bind:value={node.key}
@ -1009,6 +1052,7 @@
<input
class={inputClass}
placeholder={$i18n.t('Node Ids')}
aria-label={$i18n.t('Node Ids')}
bind:value={node.node_ids}
/>
</Tooltip>
@ -1027,8 +1071,10 @@
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
<AdminSettingField
label={$i18n.t('settings.admin.images.imagesEditGeminiApiBaseUrl.label')}
forId="images-edit-gemini-api-base-url"
>
<input
id="images-edit-gemini-api-base-url"
class={inputClass}
placeholder={$i18n.t('settings.admin.images.imagesOpenaiApiBaseUrl.label')}
bind:value={config.IMAGES_EDIT_GEMINI_API_BASE_URL}

View file

@ -345,8 +345,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.interface.tokenThreshold.label')}
description={$i18n.t('settings.admin.interface.tokenThreshold.description')}
forId="context-compaction-token-threshold"
>
<input
id="context-compaction-token-threshold"
type="number"
min="1"
step="1"
@ -358,8 +360,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.interface.tokenCap.label')}
description={$i18n.t('settings.admin.interface.tokenCap.description')}
forId="context-compaction-token-cap"
>
<input
id="context-compaction-token-cap"
type="number"
min="1"
step="1"
@ -371,8 +375,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.interface.retainedMessages.label')}
description={$i18n.t('settings.admin.interface.retainedMessages.description')}
forId="context-compaction-retained-messages"
>
<input
id="context-compaction-retained-messages"
type="number"
min="10"
max="50"
@ -433,8 +439,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.interface.toolSearchThreshold.label')}
description={$i18n.t('settings.admin.interface.toolSearchThreshold.description')}
forId="tool-search-threshold"
>
<input
id="tool-search-threshold"
type="number"
min="0"
step="1"
@ -446,8 +454,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.interface.toolSearchAlwaysLoaded.label')}
description={$i18n.t('settings.admin.interface.toolSearchAlwaysLoaded.description')}
forId="tool-search-always-loaded"
>
<input
id="tool-search-always-loaded"
class={inputClass}
type="text"
placeholder={$i18n.t('settings.admin.interface.toolSearchAlwaysLoaded.placeholder')}
@ -603,8 +613,10 @@
description={$i18n.t(
'settings.admin.interface.autocompleteGenerationInputMaxLength.description'
)}
forId="autocomplete-generation-input-max-length"
>
<input
id="autocomplete-generation-input-max-length"
type="number"
min="-1"
step="1"

View file

@ -846,6 +846,7 @@
class=" w-full text-sm py-1 rounded-r-xl outline-hidden bg-transparent"
bind:value={searchValue}
placeholder={$i18n.t('Search Models')}
aria-label={$i18n.t('Search Models')}
/>
{#if searchValue}
<div class="self-center pl-1.5 translate-y-[0.5px] rounded-l-xl bg-transparent">

View file

@ -260,13 +260,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'perplexity_search'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="perplexity-search-api-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.perplexitySearchApiUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="perplexity-search-api-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Perplexity Search API URL')}
@ -298,13 +302,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'searxng'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-left text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="searxng-query-url"
class=" self-left text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.searxngQueryUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="searxng-query-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Searxng Query URL')}
@ -316,13 +324,17 @@
</div>
</div>
<div class="mb-2.5 flex w-full flex-col">
<div class=" self-left text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="searxng-language"
class=" self-left text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.searxngSearchLanguageAllEnEsDeFrEtc.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="searxng-language"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Searxng search language')}
@ -337,13 +349,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'yacy'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="yacy-query-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.yacyInstanceUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="yacy-query-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Yacy URL (e.g. http://yacy.example.com:8090)')}
@ -357,11 +373,15 @@
<div class="mb-2.5 flex w-full flex-col">
<div class="flex gap-2">
<div class="w-full">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="yacy-username"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.yacyUsername.label')}
</div>
</label>
<input
id="yacy-username"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
placeholder={$i18n.t('Enter Yacy Username')}
bind:value={webConfig.YACY_USERNAME}
@ -396,13 +416,17 @@
/>
</div>
<div class="mt-1.5">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="google-pse-engine-id"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.googlePseEngineId.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="google-pse-engine-id"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Google PSE Engine Id')}
@ -441,13 +465,17 @@
/>
</div>
<div class="mt-1.5">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="brave-context-tokens"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.contextTokens.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="brave-context-tokens"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="number"
min="1024"
@ -545,13 +573,17 @@
/>
</div>
<div class="mt-1.5">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="serphouse-domain"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.serphouseDomain.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="serphouse-domain"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder="google.com"
@ -593,10 +625,17 @@
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="tavily-search-depth"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.tavilySearchDepth.label')}
</div>
<SettingsSelect bind:value={webConfig.TAVILY_SEARCH_DEPTH} className="w-full">
</label>
<SettingsSelect
id="tavily-search-depth"
bind:value={webConfig.TAVILY_SEARCH_DEPTH}
className="w-full"
>
<option value="ultra-fast">{$i18n.t('Ultra-fast')}</option>
<option value="fast">{$i18n.t('Fast')}</option>
<option value="basic">{$i18n.t('Basic')}</option>
@ -662,13 +701,17 @@
/>
</div>
<div class="mt-1.5">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="searchapi-engine"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.searchapiEngine.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="searchapi-engine"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter SearchApi Engine')}
@ -693,13 +736,17 @@
/>
</div>
<div class="mt-1.5">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="serpapi-engine"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.serpapiEngine.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="serpapi-engine"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter SerpApi Engine')}
@ -713,13 +760,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'jina'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="jina-api-base-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.jinaApiBaseUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="jina-api-base-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Jina API Base URL')}
@ -745,13 +796,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'bing'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="bing-search-v7-endpoint"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.bingSearchV7Endpoint.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="bing-search-v7-endpoint"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Bing Search V7 Endpoint')}
@ -821,10 +876,14 @@
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class="self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="perplexity-model"
class="self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.perplexityModel.label')}
</div>
</label>
<input
id="perplexity-model"
list="perplexity-model-list"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
bind:value={webConfig.PERPLEXITY_MODEL}
@ -842,10 +901,14 @@
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="perplexity-search-context-usage"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.perplexitySearchContextUsage.label')}
</div>
</label>
<SettingsSelect
id="perplexity-search-context-usage"
bind:value={webConfig.PERPLEXITY_SEARCH_CONTEXT_USAGE}
className="w-full"
>
@ -858,13 +921,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'microsoft_web_iq'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="microsoft-web-iq-api-base-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.microsoftWebIqApiBaseUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="microsoft-web-iq-api-base-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Microsoft Web IQ API Base URL')}
@ -888,11 +955,15 @@
</div>
<div class="mt-2">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="microsoft-web-iq-language"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.language.label')}
</div>
</label>
<input
id="microsoft-web-iq-language"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter language')}
@ -931,13 +1002,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'firecrawl'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="firecrawl-api-base-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.firecrawlApiBaseUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="firecrawl-api-base-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Firecrawl API Base URL')}
@ -961,13 +1036,17 @@
</div>
<div class="mt-2">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="firecrawl-timeout"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.firecrawlTimeoutS.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="firecrawl-timeout"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="number"
placeholder={$i18n.t('Enter Firecrawl Timeout')}
@ -981,13 +1060,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'external'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="external-web-search-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.externalWebSearchUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="external-web-search-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter External Web Search URL')}
@ -1013,13 +1096,17 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'yandex'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="yandex-web-search-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.yandexWebSearchUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="yandex-web-search-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Yandex Web Search URL')}
@ -1106,12 +1193,16 @@
{:else if webConfig.WEB_SEARCH_ENGINE === 'openserp'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="openserp-base-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.openserpUrl.label')}
</div>
</label>
<div class="flex-1">
<input
id="openserp-base-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter OpenSERP Base URL')}
@ -1127,13 +1218,20 @@
{#if webConfig.WEB_SEARCH_ENGINE === 'duckduckgo'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="ddgs-backend"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.ddgsBackend.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<SettingsSelect bind:value={webConfig.DDGS_BACKEND} className="w-full">
<SettingsSelect
id="ddgs-backend"
bind:value={webConfig.DDGS_BACKEND}
className="w-full"
>
<option value="auto">{$i18n.t('Auto (Random)')}</option>
<option value="bing">{$i18n.t('Bing')}</option>
<option value="brave">{$i18n.t('Brave')}</option>
@ -1159,11 +1257,15 @@
>
<div class="flex gap-2">
<div class="w-full">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="web-search-result-count"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.searchResultCount.label')}
</div>
</label>
<input
id="web-search-result-count"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
placeholder={$i18n.t('settings.admin.web.searchResultCount.label')}
bind:value={webConfig.WEB_SEARCH_RESULT_COUNT}
@ -1172,16 +1274,20 @@
</div>
<div class="w-full">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="web-search-concurrent-requests"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
<Tooltip
content={$i18n.t('settings.admin.web.searchResultCount.description')}
placement="top-start"
>
{$i18n.t('settings.admin.web.concurrentRequests.label')}
</Tooltip>
</div>
</label>
<input
id="web-search-concurrent-requests"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
placeholder={$i18n.t('settings.admin.web.concurrentRequests.label')}
bind:value={webConfig.WEB_SEARCH_CONCURRENT_REQUESTS}
@ -1195,8 +1301,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.web.fetchUrlContentLengthLimit.label')}
description={$i18n.t('settings.admin.web.fetchUrlContentLengthLimit.description')}
forId="web-fetch-max-content-length"
>
<input
id="web-fetch-max-content-length"
class={inputClass}
placeholder={$i18n.t('No limit')}
bind:value={webConfig.WEB_FETCH_MAX_CONTENT_LENGTH}
@ -1208,8 +1316,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.web.domainFilterList.label')}
description={$i18n.t('settings.admin.web.domainFilterList.description')}
forId="web-search-domain-filter-list"
>
<input
id="web-search-domain-filter-list"
class={inputClass}
placeholder={$i18n.t(
'Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)'
@ -1296,8 +1406,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.web.timeout.label')}
description={$i18n.t('settings.admin.web.timeout.description')}
forId="web-loader-timeout"
>
<input
id="web-loader-timeout"
class={inputClass}
placeholder={$i18n.t('settings.admin.web.timeout.label')}
bind:value={webConfig.WEB_LOADER_TIMEOUT}
@ -1317,13 +1429,17 @@
{:else if webConfig.WEB_LOADER_ENGINE === 'playwright'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="playwright-ws-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.playwrightWebsocketUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="playwright-ws-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Playwright WebSocket URL')}
@ -1335,13 +1451,17 @@
</div>
<div class="mt-2">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="playwright-timeout"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.playwrightTimeoutMs.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="playwright-timeout"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
placeholder={$i18n.t('Enter Playwright Timeout')}
bind:value={webConfig.PLAYWRIGHT_TIMEOUT}
@ -1354,13 +1474,17 @@
{:else if webConfig.WEB_LOADER_ENGINE === 'firecrawl' && (!webConfig.ENABLE_WEB_SEARCH || webConfig.WEB_SEARCH_ENGINE !== 'firecrawl')}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="web-loader-firecrawl-api-base-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.firecrawlApiBaseUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="web-loader-firecrawl-api-base-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Firecrawl API Base URL')}
@ -1386,13 +1510,17 @@
{:else if webConfig.WEB_LOADER_ENGINE === 'tavily'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="tavily-extract-depth"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.tavilyExtractDepth.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="tavily-extract-depth"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Tavily Extract Depth')}
@ -1421,13 +1549,17 @@
<div class="mb-2.5 flex w-full flex-col">
{#if !webConfig.ENABLE_WEB_SEARCH || webConfig.WEB_SEARCH_ENGINE !== 'microsoft_web_iq'}
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="web-loader-microsoft-web-iq-api-base-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.microsoftWebIqApiBaseUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="web-loader-microsoft-web-iq-api-base-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter Microsoft Web IQ API Base URL')}
@ -1451,11 +1583,15 @@
</div>
<div class="mt-2">
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="web-loader-microsoft-web-iq-language"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.language.label')}
</div>
</label>
<input
id="web-loader-microsoft-web-iq-language"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter language')}
@ -1468,13 +1604,17 @@
{:else if webConfig.WEB_LOADER_ENGINE === 'external'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1">
<label
for="external-web-loader-url"
class=" self-center text-xs text-gray-600 dark:text-gray-400 mb-1 block"
>
{$i18n.t('settings.admin.web.externalWebLoaderUrl.label')}
</div>
</label>
<div class="flex w-full">
<div class="flex-1">
<input
id="external-web-loader-url"
class="w-full rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 py-1.5 text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="text"
placeholder={$i18n.t('Enter External Web Loader URL')}
@ -1502,8 +1642,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.web.concurrentRequests.label')}
description={$i18n.t('settings.admin.web.concurrentRequests.description')}
forId="web-loader-concurrent-requests"
>
<input
id="web-loader-concurrent-requests"
class={inputClass}
placeholder={$i18n.t('settings.admin.web.concurrentRequests.label')}
bind:value={webConfig.WEB_LOADER_CONCURRENT_REQUESTS}
@ -1514,8 +1656,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.web.youtubeLanguage.label')}
description={$i18n.t('settings.admin.web.youtubeLanguage.description')}
forId="youtube-loader-language"
>
<input
id="youtube-loader-language"
class={inputClass}
type="text"
placeholder={$i18n.t('Enter language codes')}
@ -1527,8 +1671,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.web.youtubeProxyUrl.label')}
description={$i18n.t('settings.admin.web.youtubeProxyUrl.description')}
forId="youtube-loader-proxy-url"
>
<input
id="youtube-loader-proxy-url"
class={inputClass}
type="text"
placeholder={$i18n.t('Enter proxy URL (e.g. https://user:password@host:port)')}