ui : scope the model list to the active backend tab

Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
Aleksander Grygier
2026-09-16 19:22:47 +02:00
parent ee41ebc15d
commit 4761edc102
4 changed files with 48 additions and 28 deletions
@@ -342,6 +342,7 @@
<ModelsSelectorList
activeId={ms.activeId}
{currentModel}
flat={!ms.isLocalBackend}
groups={ms.groupedFilteredOptions}
onInfoClick={ms.handleInfoClick}
onSelect={ms.handleSelect}
@@ -10,6 +10,8 @@
groups: GroupedModelOptions;
currentModel: string | null;
activeId: string | null;
/** Render one flat list without section headers (external backends). */
flat?: boolean;
sectionHeaderClass?: string;
onSelect: (modelId: string) => void;
onInfoClick: (modelName: string) => void;
@@ -19,6 +21,7 @@
let {
activeId,
currentModel,
flat = false,
groups,
onInfoClick,
onSelect,
@@ -61,38 +64,44 @@
/>
{/snippet}
{#if groups.favorites.length > 0}
<p class={sectionHeaderClass}>Favorite models</p>
{#each groups.favorites as item (`fav-${item.option.id}`)}
{#if flat}
{#each [...groups.favorites, ...groups.available.flatMap((group) => group.items)] as item (item.option.id)}
{@render render(item, true)}
{/each}
{/if}
{:else}
{#if groups.favorites.length > 0}
<p class={sectionHeaderClass}>Favorite models</p>
{#if getDownloadEntries.length > 0}
<p class={sectionHeaderClass}>Download in progress</p>
{#each getDownloadEntries as entry (entry.repoWithTag)}
<ModelsSelectorDownloadItem {entry} onRequestCancel={requestCancel} />
{/each}
{/if}
{#if groups.loaded.length > 0}
<p class={sectionHeaderClass}>Loaded models</p>
{#each groups.loaded as item (`loaded-${item.option.id}`)}
{@render render(item, false)}
{/each}
{/if}
{#if groups.available.length > 0}
<h2 class={sectionHeaderClass}>Downloaded models</h2>
{#each groups.available as group (group.orgName)}
{#each group.items as item (item.option.id)}
{#each groups.favorites as item (`fav-${item.option.id}`)}
{@render render(item, true)}
{/each}
{/each}
{/if}
{#if getDownloadEntries.length > 0}
<p class={sectionHeaderClass}>Download in progress</p>
{#each getDownloadEntries as entry (entry.repoWithTag)}
<ModelsSelectorDownloadItem {entry} onRequestCancel={requestCancel} />
{/each}
{/if}
{#if groups.loaded.length > 0}
<p class={sectionHeaderClass}>Loaded models</p>
{#each groups.loaded as item (`loaded-${item.option.id}`)}
{@render render(item, false)}
{/each}
{/if}
{#if groups.available.length > 0}
<h2 class={sectionHeaderClass}>Downloaded models</h2>
{#each groups.available as group (group.orgName)}
{#each group.items as item (item.option.id)}
{@render render(item, true)}
{/each}
{/each}
{/if}
{/if}
<DialogConfirmDownload
@@ -188,6 +188,7 @@
<ModelsSelectorList
activeId={ms.activeId}
{currentModel}
flat={!ms.isLocalBackend}
groups={ms.groupedFilteredOptions}
onInfoClick={ms.handleInfoClick}
onSelect={ms.handleSelect}
@@ -21,6 +21,7 @@ export interface UseModelsSelectorReturn {
readonly updating: boolean;
readonly activeId: string | null;
readonly activeBackendId: string;
readonly isLocalBackend: boolean;
readonly backends: Backend[];
readonly isMultiModel: boolean;
readonly isRouter: boolean;
@@ -51,8 +52,13 @@ export interface UseModelsSelectorReturn {
* duplicating store derivations, selection handling, and model loading.
*/
export function useModelsSelector(opts: UseModelsSelectorOptions): UseModelsSelectorReturn {
const activeBackendId = $derived(backendsStore.active.id);
const isLocalBackend = $derived(backendsStore.active.protocol === 'llama.cpp');
// the backend switcher tabs scope the list to one backend's models
const options = $derived(
modelsStore.models.filter((option) => {
if (option.backendId !== activeBackendId) return false;
const modelProps = modelsStore.props.getModelProps(option.model);
return modelProps?.ui !== false;
@@ -61,7 +67,6 @@ export function useModelsSelector(opts: UseModelsSelectorOptions): UseModelsSele
const loading = $derived(modelsStore.loading);
const updating = $derived(modelsStore.updating);
const activeId = $derived(modelsStore.selectedModelId);
const activeBackendId = $derived(backendsStore.active.id);
const backends = $derived(backendsStore.enabled);
// Router mode and external backends both expose a selectable model list;
// a single-model llama.cpp server does not.
@@ -272,6 +277,10 @@ export function useModelsSelector(opts: UseModelsSelectorOptions): UseModelsSele
return isLoadingModel;
},
get isLocalBackend() {
return isLocalBackend;
},
get isMultiModel() {
return isMultiModel;
},