From db4fc4fe2e08dbb79eaccf172e17c405c2471927 Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Fri, 25 Sep 2026 08:59:41 +0200 Subject: [PATCH] ui : show the provider's mark on the model selector trigger Assisted-by: pi:llama.cpp/GLM-5.3-Flash --- .../app/backends/BackendIcon.svelte | 2 +- .../components/app/models/ModelAvatar.svelte | 10 ++++-- .../ModelsSelectorDropdown.svelte | 7 ++-- .../ModelsSelector/ModelsSelectorSheet.svelte | 7 ++-- .../ModelsSelectorTriggerIcon.svelte | 32 +++++++++++++++++++ .../app/models/ModelsSelector/index.ts | 9 ++++++ tools/ui/src/lib/constants/ui.constants.ts | 4 +-- 7 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorTriggerIcon.svelte diff --git a/tools/ui/src/lib/components/app/backends/BackendIcon.svelte b/tools/ui/src/lib/components/app/backends/BackendIcon.svelte index c221a36c65..d9ed53a518 100644 --- a/tools/ui/src/lib/components/app/backends/BackendIcon.svelte +++ b/tools/ui/src/lib/components/app/backends/BackendIcon.svelte @@ -15,7 +15,7 @@ fallback?: Snippet; } - let { backend, class: className = 'h-4 w-4', fallback }: Props = $props(); + let { backend, class: className = 'size-4', fallback }: Props = $props(); let preset = $derived(backend ? findBackendPreset(backend.baseUrl) : undefined); let faviconUrl = $derived(preset || !backend ? null : backendFaviconUrl(backend.baseUrl)); diff --git a/tools/ui/src/lib/components/app/models/ModelAvatar.svelte b/tools/ui/src/lib/components/app/models/ModelAvatar.svelte index 7f9ca08f73..2c7051a868 100644 --- a/tools/ui/src/lib/components/app/models/ModelAvatar.svelte +++ b/tools/ui/src/lib/components/app/models/ModelAvatar.svelte @@ -2,7 +2,7 @@ import ModelsDiscoverAvatar from './discover/ModelsDiscoverAvatar.svelte'; import { BackendIcon } from '$lib/components/app/backends'; import { Logo } from '$lib/components/app/misc'; - import { HF_BASE_MODEL_TAG_REGEX } from '$lib/constants'; + import { HF_BASE_MODEL_TAG_REGEX, LOCAL_BACKEND_ID, MODEL_SELECTOR_ICON } from '$lib/constants'; import { HuggingFaceService, ModelsService } from '$lib/services'; import type { ModelOption } from '$lib/types/models'; import { orgOf } from '$lib/utils'; @@ -43,6 +43,8 @@ // so the provider's own mark identifies it better than an initial let isLlamaCompat = $derived(getBackendCapabilities(getBackend(option.backendId)).props); let useProviderIcon = $derived(isLlamaCompat && !orgName); + // the bundled server has no favicon to resolve, its mark is the llama.cpp logo + let isLocal = $derived(getBackend(option.backendId)?.id === LOCAL_BACKEND_ID); let tagBaseModel = $derived( (option.tags ?? []) .find((t) => HF_BASE_MODEL_TAG_REGEX.test(t)) @@ -109,7 +111,11 @@ {#snippet fallback()} - + {#if isLocal} + + {:else} + + {/if} {/snippet} diff --git a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorDropdown.svelte b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorDropdown.svelte index f0214d9e45..882d6c833c 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorDropdown.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorDropdown.svelte @@ -6,7 +6,8 @@ ModelId, ModelsSelectorList, ModelsSelectorOption, - ModelsSelectorReasoningPanel + ModelsSelectorReasoningPanel, + ModelsSelectorTriggerIcon } from '$lib/components/app'; import { DialogBackendForm } from '$lib/components/app/backends'; import type { ModelItem } from '$lib/components/app/navigation/utils'; @@ -250,7 +251,7 @@ ]} disabled={disabled || ms.updating} > - + {#if selectedOption} @@ -409,7 +410,7 @@ onclick={() => ms.handleOpenChange(true)} style="max-width: min(calc(100cqw - 6.5rem), 32rem)" > - + {#if selectedOption} import ModelLoadHighlight from '../ModelLoadHighlight.svelte'; - import { ChevronDown, Lightbulb, Loader2, Package } from '@lucide/svelte'; + import { ChevronDown, Lightbulb, Loader2 } from '@lucide/svelte'; import { ModelId, ModelsSelectorList, ModelsSelectorReasoningPanel, + ModelsSelectorTriggerIcon, SearchInput } from '$lib/components/app'; import { DialogBackendForm } from '$lib/components/app/backends'; @@ -120,7 +121,7 @@ style="max-width: min(calc(100cqw - 9rem), 20rem)" type="button" > - + {#if !selectedOption} Select model @@ -225,7 +226,7 @@ onclick={() => ms.handleOpenChange(true)} style="max-width: min(calc(100cqw - 6.5rem), 32rem)" > - + + import { BackendIcon } from '$lib/components/app/backends'; + import { Logo } from '$lib/components/app/misc'; + import { LOCAL_BACKEND_ID, MODEL_SELECTOR_ICON } from '$lib/constants'; + import type { ModelOption } from '$lib/types/models'; + import { getBackend } from '$lib/utils/api-base'; + + interface Props { + class?: string; + /** Selected model; its provider decides the mark, the generic icon when absent. */ + option?: ModelOption | null; + } + + let { class: className = 'size-1', option }: Props = $props(); + + // the bundled server has no favicon to resolve, its mark is the llama.cpp logo + let isLocal = $derived(getBackend(option?.backendId)?.id === LOCAL_BACKEND_ID); + + +{#if option} + + {#snippet fallback()} + {#if isLocal} + + {:else} + + {/if} + {/snippet} + +{:else} + +{/if} diff --git a/tools/ui/src/lib/components/app/models/ModelsSelector/index.ts b/tools/ui/src/lib/components/app/models/ModelsSelector/index.ts index cb563b38a3..6bcab3c7b4 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelector/index.ts +++ b/tools/ui/src/lib/components/app/models/ModelsSelector/index.ts @@ -100,3 +100,12 @@ export { default as ModelsSelectorReasoningPanel } from './ModelsSelectorReasoni * instead of DropdownMenu. */ export { default as ModelsSelectorSheet } from './ModelsSelectorSheet.svelte'; + +/** + * **ModelsSelectorTriggerIcon** - Icon for the selector trigger button + * + * Shows the selected model's provider mark (preset logo or favicon) and falls + * back to the generic model icon when the provider has none. The bundled local + * server falls back to the llama.cpp logo. + */ +export { default as ModelsSelectorTriggerIcon } from './ModelsSelectorTriggerIcon.svelte'; diff --git a/tools/ui/src/lib/constants/ui.constants.ts b/tools/ui/src/lib/constants/ui.constants.ts index 43305cf9dc..231c756cc5 100644 --- a/tools/ui/src/lib/constants/ui.constants.ts +++ b/tools/ui/src/lib/constants/ui.constants.ts @@ -1,4 +1,4 @@ -import { Box, Package, Search, Settings, SquarePen } from '@lucide/svelte'; +import { Package, Search, Settings, SquarePen } from '@lucide/svelte'; import { SidebarAction, ToolSource } from '$lib/enums'; import type { DesktopIconStripItem } from '$lib/types'; @@ -83,7 +83,7 @@ export const SIDEBAR_ACTIONS_ITEMS: DesktopIconStripItem[] = [ { icon: Search, keys: ['cmd', 'k'], tooltip: 'Search' }, { action: SidebarAction.MANAGE_MODELS, - icon: Box, + icon: MODEL_SELECTOR_ICON, tooltip: 'Models' }, {