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)
);