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 ef11bb5ccf..9142c12a4d 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorDropdown.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorDropdown.svelte @@ -323,11 +323,7 @@

{ms.emptyMessage}

{/if} - {#snippet modelOption( - item: ModelItem, - hideOrgName: boolean, - showFavIndicator: boolean - )} + {#snippet modelOption(item: ModelItem, hideOrgName: boolean)} {@const { option } = item} {@const isSelected = currentModel === option.model || ms.activeId === option.id} {@const isHighlighted = option.id === highlightedId} @@ -349,7 +345,6 @@ onSelect={ms.handleSelect} {option} showBaseModelAvatar - {showFavIndicator} /> {/snippet} diff --git a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorList.svelte b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorList.svelte index 5f3da80536..c523b48a00 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorList.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorList.svelte @@ -17,7 +17,7 @@ sectionHeaderClass?: string; onSelect: (modelId: string) => void; onInfoClick: (modelName: string) => void; - renderOption?: import('svelte').Snippet<[ModelItem, boolean, boolean]>; + renderOption?: import('svelte').Snippet<[ModelItem, boolean]>; /** Favorite models of every backend, listed in their own section. */ favorites?: ModelItem[]; /** Show the organization name in every model id of the list. */ @@ -63,7 +63,7 @@ } -{#snippet defaultOption(item: ModelItem, hideOrgName: boolean, showFavIndicator: boolean)} +{#snippet defaultOption(item: ModelItem, hideOrgName: boolean)} {@const { option } = item} {@const isSelected = currentModel === option.model || activeId === option.id} {@const isFav = modelsStore.favoriteModelIds.has(option.model)} @@ -79,11 +79,11 @@ {onSelect} {option} showBaseModelAvatar - {showFavIndicator} /> {/snippet} {#if favorites.length > 0} + {/if} @@ -123,12 +123,12 @@ {/snippet} {#each groups.loaded as item (`loaded-${item.option.id}`)} - {@render render(item, !showOrgName, true)} + {@render render(item, !showOrgName)} {/each} {#each groups.available as group (group.orgName)} {#each group.items as item (item.option.id)} - {@render render(item, !showOrgName, true)} + {@render render(item, !showOrgName)} {/each} {/each} @@ -168,7 +168,7 @@ {#if provider.items.length > 0} {#each provider.items as item (`${provider.backendId}-${item.option.id}`)} - {@render render(item, !showOrgName, true)} + {@render render(item, !showOrgName)} {/each} {#if onProviderOpen && provider.matched > provider.items.length} diff --git a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorOption.svelte b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorOption.svelte index a9aab3d057..244ea38c92 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorOption.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsSelector/ModelsSelectorOption.svelte @@ -26,9 +26,6 @@ isSelected: boolean; isHighlighted: boolean; isFav: boolean; - /** Show the filled heart at rest. Off inside the favorites section, where - * every row is a favorite. */ - showFavIndicator?: boolean; hideOrgName?: boolean; onSelect: (modelId: string) => void; onMouseEnter: () => void; @@ -48,8 +45,7 @@ onMouseEnter, onSelect, option, - showBaseModelAvatar = false, - showFavIndicator = true + showBaseModelAvatar = false }: Props = $props(); // row actions follow the backend that serves the row, not the selected one @@ -167,8 +163,7 @@
e.stopPropagation()} diff --git a/tools/ui/src/lib/hooks/use-models-selector.svelte.ts b/tools/ui/src/lib/hooks/use-models-selector.svelte.ts index ea45a158ab..886211c82a 100644 --- a/tools/ui/src/lib/hooks/use-models-selector.svelte.ts +++ b/tools/ui/src/lib/hooks/use-models-selector.svelte.ts @@ -145,9 +145,13 @@ export function useModelsSelector(opts: UseModelsSelectorOptions): UseModelsSele }; }) ); + // favorites are listed once, at the top: the sections below skip them + const sectionOptions = $derived( + filteredOptions.filter((option) => !modelsStore.favoriteModelIds.has(option.model)) + ); const providerSections = $derived( groupProviderOptions( - filteredOptions, + sectionOptions, remoteProviders, // a drill-in or a search reaches every model, the sections stay short providerViewId || searchTerm ? Infinity : REMOTE_PROVIDER_MODEL_LIMIT @@ -160,7 +164,7 @@ export function useModelsSelector(opts: UseModelsSelectorOptions): UseModelsSele return { ...EMPTY_GROUPS, providers: sections }; } - const local = groupModelOptions(filteredOptions.filter(isLocalOption), (m) => + const local = groupModelOptions(sectionOptions.filter(isLocalOption), (m) => modelsStore.isModelLoaded(m) );