ui : show the provider's mark on the model selector trigger

Assisted-by: pi:llama.cpp/GLM-5.3-Flash
This commit is contained in:
Aleksander Grygier
2026-09-28 12:10:13 +02:00
parent 3eb568e8f1
commit db4fc4fe2e
7 changed files with 60 additions and 11 deletions
@@ -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));
@@ -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 @@
<span class={['inline-flex shrink-0', className]}>
<BackendIcon backend={getBackend(option.backendId)} class={size}>
{#snippet fallback()}
<Logo class={size} style="--size: 100%" />
{#if isLocal}
<Logo class={size} style="--size: 100%" />
{:else}
<MODEL_SELECTOR_ICON class={size} />
{/if}
{/snippet}
</BackendIcon>
</span>
@@ -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}
>
<MODEL_SELECTOR_ICON class="h-3.5 w-3.5 shrink-0" />
<ModelsSelectorTriggerIcon class="size-3.5 shrink-0 mr-0.375" option={selectedOption} />
<span class="flex min-w-0 items-center gap-0.5">
{#if selectedOption}
@@ -409,7 +410,7 @@
onclick={() => ms.handleOpenChange(true)}
style="max-width: min(calc(100cqw - 6.5rem), 32rem)"
>
<MODEL_SELECTOR_ICON class="h-3.5 w-3.5 shrink-0" />
<ModelsSelectorTriggerIcon class="size-3.5 shrink-0 mr-0.375" option={selectedOption} />
{#if selectedOption}
<ModelId
@@ -1,10 +1,11 @@
<script lang="ts">
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"
>
<Package class="h-3.5 w-3.5 shrink-0" />
<ModelsSelectorTriggerIcon class="h-3.5 w-3.5 shrink-0" option={selectedOption} />
{#if !selectedOption}
<span class="min-w-0 font-medium">Select model</span>
@@ -225,7 +226,7 @@
onclick={() => ms.handleOpenChange(true)}
style="max-width: min(calc(100cqw - 6.5rem), 32rem)"
>
<Package class="h-3.5 w-3.5 shrink-0" />
<ModelsSelectorTriggerIcon class="h-3.5 w-3.5 shrink-0" option={selectedOption} />
<ModelId
class="font-medium"
@@ -0,0 +1,32 @@
<script lang="ts">
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);
</script>
{#if option}
<BackendIcon backend={getBackend(option.backendId)} class={className}>
{#snippet fallback()}
{#if isLocal}
<Logo class={className} style="--size: 95%; margin-top: 1px;" />
{:else}
<MODEL_SELECTOR_ICON class={className} />
{/if}
{/snippet}
</BackendIcon>
{:else}
<MODEL_SELECTOR_ICON class={className} />
{/if}
@@ -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';
+2 -2
View File
@@ -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'
},
{