From e5b24a22d0f5003ca1226196991a9d2e0bc384cb Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 11 Aug 2026 03:27:12 +0200 Subject: [PATCH] fix: model ID whitelists accepting duplicate entries (#28251) Adding a model ID that was already on the list in the connection settings modal simply appended it again, so the same model could sit in the whitelist any number of times. The arena model modal had the same flaw, its dropdown kept offering models that were already selected. The connection modal now rejects a duplicate with a toast and trims the input first; surrounding whitespace renders invisibly in the list, so an untrimmed ID would slip past the duplicate check and still show up as a visually identical row. The arena modal instead filters already-added models out of the dropdown, matching the existing model selector in the admin settings, so a duplicate can no longer be picked at all. Both modals also drop duplicates when loading a stored list, so configs that already contain them are cleaned on their next save. Until such a config is re-saved, one residual effect of old data remains: a duplicated ID in an arena model's stored list keeps double weight in the random model draw. New duplicates can no longer be created through the UI. Fixes #28249 --- src/lib/components/AddConnectionModal.svelte | 17 +++++++++++++---- .../Settings/Evaluations/ArenaModelModal.svelte | 8 ++++---- src/lib/i18n/locales/en-US/translation.json | 1 + 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/lib/components/AddConnectionModal.svelte b/src/lib/components/AddConnectionModal.svelte index 16616fc247..68eb96b70f 100644 --- a/src/lib/components/AddConnectionModal.svelte +++ b/src/lib/components/AddConnectionModal.svelte @@ -140,10 +140,19 @@ }; const addModelHandler = () => { - if (modelId) { - modelIds = [...modelIds, modelId]; - modelId = ''; + const newModelId = modelId.trim(); + + if (!newModelId) { + return; } + + if (modelIds.includes(newModelId)) { + toast.error($i18n.t('Model ID is already added')); + return; + } + + modelIds = [...modelIds, newModelId]; + modelId = ''; }; const submitHandler = async () => { @@ -245,7 +254,7 @@ passthroughParams = Array.isArray(connection.config?.passthrough_params) ? connection.config.passthrough_params.join(', ') : (connection.config?.passthrough_params ?? ''); - modelIds = connection.config?.model_ids ?? []; + modelIds = [...new Set(connection.config?.model_ids ?? [])]; if (ollama) { connectionType = connection.config?.connection_type ?? 'local'; diff --git a/src/lib/components/admin/Settings/Evaluations/ArenaModelModal.svelte b/src/lib/components/admin/Settings/Evaluations/ArenaModelModal.svelte index ec8d997233..7f2667e35d 100644 --- a/src/lib/components/admin/Settings/Evaluations/ArenaModelModal.svelte +++ b/src/lib/components/admin/Settings/Evaluations/ArenaModelModal.svelte @@ -54,10 +54,10 @@ let showDeleteConfirmDialog = false; const addModelHandler = () => { - if (selectedModelId) { + if (selectedModelId && !modelIds.includes(selectedModelId)) { modelIds = [...modelIds, selectedModelId]; - selectedModelId = ''; } + selectedModelId = ''; }; const submitHandler = () => { @@ -111,7 +111,7 @@ id = model.id; profileImageUrl = model.meta.profile_image_url; description = model.meta.description; - modelIds = model.meta.model_ids || []; + modelIds = [...new Set(model.meta.model_ids || [])]; filterMode = model.meta?.filter_mode ?? 'include'; accessGrants = model.meta.access_grants ?? []; } @@ -362,7 +362,7 @@ bind:value={selectedModelId} > - {#each $models.filter((m) => m?.owned_by !== 'arena') as model} + {#each $models.filter((m) => m?.owned_by !== 'arena' && !modelIds.includes(m?.id)) as model} {/each} diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index da7da2fb01..1f15676d7f 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -1700,6 +1700,7 @@ "Model filesystem path detected. Model shortname is required for update, cannot continue.": "", "Model Filtering": "", "Model ID": "", + "Model ID is already added": "", "Model ID is required.": "", "Model IDs": "", "Model is now private": "",