ui : apply the org name setting to every model id in the selector

Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
Aleksander Grygier
2026-09-16 23:01:58 +02:00
parent 5fd7983784
commit 709e871a6f
7 changed files with 69 additions and 25 deletions
@@ -15,9 +15,11 @@
* the list renders a single shared confirmation.
*/
onRequestCancel?: (repoWithTag: string) => void;
/** Show the organization name in the repo id, as the other selector rows do. */
showOrgName?: boolean;
}
let { entry, onRequestCancel }: Props = $props();
let { entry, onRequestCancel, showOrgName = true }: Props = $props();
let percent = $derived(
entry.progress && entry.progress.totalBytes > 0
@@ -79,7 +81,7 @@
/>
{/if}
<ModelId class="flex-1" hideOrgName modelId={entry.repoWithTag} showRawTooltip />
<ModelId class="flex-1" hideOrgName={!showOrgName} modelId={entry.repoWithTag} showRawTooltip />
{#if percent !== null}
<span class="shrink-0 font-mono text-xs tabular-nums text-muted-foreground">{percent}%</span>
@@ -76,9 +76,8 @@
const selectedOption = $derived(ms.getDisplayOption());
const triggerModel = $derived(selectedOption?.model ?? null);
const showOrgNameInTrigger = $derived(
settingsStore.config[SETTINGS_KEYS.SHOW_MODEL_ORG_NAME_IN_TRIGGER] ?? false
);
// one setting for every model id in the selector: the trigger and the rows
const showOrgName = $derived(settingsStore.config[SETTINGS_KEYS.SHOW_MODEL_ORG_NAME] ?? true);
$effect(() => {
void ms.searchTerm;
@@ -240,7 +239,7 @@
{#if selectedOption}
<ModelId
class="min-w-0 overflow-hidden"
hideOrgName={!showOrgNameInTrigger}
hideOrgName={!showOrgName}
hideQuantization
modelId={selectedOption.model}
/>
@@ -309,7 +308,12 @@
role="option"
type="button"
>
<ModelId class="flex-1" hideQuantization modelId={currentModel} />
<ModelId
class="flex-1"
hideOrgName={!showOrgName}
hideQuantization
modelId={currentModel}
/>
<span class="ml-2 text-xs whitespace-nowrap opacity-70">(not available)</span>
</button>
@@ -319,14 +323,14 @@
<p class="px-4 py-3 text-sm text-muted-foreground">{ms.emptyMessage}</p>
{/if}
{#snippet modelOption(item: ModelItem, _hideOrgName: boolean)}
{#snippet modelOption(item: ModelItem, hideOrgName: boolean)}
{@const { option } = item}
{@const isSelected = currentModel === option.model || ms.activeId === option.id}
{@const isHighlighted = option.id === highlightedId}
{@const isFav = ms.isFavorite(option.model)}
<ModelsSelectorOption
hideOrgName
{hideOrgName}
{isFav}
{isHighlighted}
{isSelected}
@@ -355,6 +359,7 @@
onSelect={ms.handleSelect}
renderOption={modelOption}
sectionHeaderClass="[&:not(:first-child)]:mt-3 mb-1 px-2 py-2 text-[13px] font-semibold text-muted-foreground/70 select-none"
{showOrgName}
/>
</div>
@@ -400,7 +405,7 @@
{#if selectedOption}
<ModelId
class="min-w-0 overflow-hidden"
hideOrgName={!showOrgNameInTrigger}
hideOrgName={!showOrgName}
hideQuantization
modelId={selectedOption.model}
/>
@@ -17,6 +17,8 @@
renderOption?: import('svelte').Snippet<[ModelItem, boolean]>;
/** Favorite models of every backend; shown on the favorites tab. */
favorites?: ModelItem[];
/** Show the organization name in every model id of the list. */
showOrgName?: boolean;
/** Open one provider's full list, offered when a section is cut short. */
onProviderOpen?: (backendId: string) => void;
/** Leave the drilled-in provider; enables the back affordance. */
@@ -33,7 +35,8 @@
onProviderOpen,
onSelect,
renderOption,
sectionHeaderClass = 'm-0 px-2 py-2 text-[13px] font-semibold text-muted-foreground/70 select-none'
sectionHeaderClass = 'm-0 px-2 py-2 text-[13px] font-semibold text-muted-foreground/70 select-none',
showOrgName = true
}: Props = $props();
let render = $derived(renderOption ?? defaultOption);
// section headers stick right below the search/tabs block of the dropdown
@@ -57,13 +60,13 @@
}
</script>
{#snippet defaultOption(item: ModelItem, _hideOrgName: 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)}
<ModelsSelectorOption
hideOrgName
{hideOrgName}
{isFav}
isHighlighted={false}
{isSelected}
@@ -78,25 +81,25 @@
<!-- Favorites tab: rows only, the tab already names the view. -->
{#each favorites as item (`fav-${item.option.id}`)}
{@render render(item, true)}
{@render render(item, !showOrgName)}
{/each}
{#if getDownloadEntries.length > 0}
<p class={headerClass} style={headerStyle}>Download in progress</p>
{#each getDownloadEntries as entry (entry.repoWithTag)}
<ModelsSelectorDownloadItem {entry} onRequestCancel={requestCancel} />
<ModelsSelectorDownloadItem {entry} onRequestCancel={requestCancel} {showOrgName} />
{/each}
{/if}
<!-- Local view: one list, the loaded models first, no section headers. -->
{#each groups.loaded as item (`loaded-${item.option.id}`)}
{@render render(item, false)}
{@render render(item, !showOrgName)}
{/each}
{#each groups.available as group (group.orgName)}
{#each group.items as item (item.option.id)}
{@render render(item, true)}
{@render render(item, !showOrgName)}
{/each}
{/each}
@@ -125,7 +128,7 @@
{#if provider.items.length > 0}
{#each provider.items as item (`${provider.backendId}-${item.option.id}`)}
{@render render(item, true)}
{@render render(item, !showOrgName)}
{/each}
{#if onProviderOpen && provider.matched > provider.items.length}
@@ -11,10 +11,11 @@
} from '$lib/components/app';
import { DialogBackendForm } from '$lib/components/app/backends';
import * as Sheet from '$lib/components/ui/sheet';
import { SETTINGS_KEYS } from '$lib/constants';
import { ServerModelStatus } from '$lib/enums';
import { useModelsSelector } from '$lib/hooks/use-models-selector.svelte';
import { useReasoningMenu } from '$lib/hooks/use-reasoning-menu.svelte';
import { modelsStore } from '$lib/stores';
import { modelsStore, settingsStore } from '$lib/stores';
import { modelLoadFraction } from '$lib/utils';
interface Props {
@@ -50,6 +51,8 @@
});
const reasoning = useReasoningMenu();
// one setting for every model id in the selector: the trigger and the rows
const showOrgName = $derived(settingsStore.config[SETTINGS_KEYS.SHOW_MODEL_ORG_NAME] ?? true);
export function open() {
ms.handleOpenChange(true);
@@ -195,6 +198,7 @@
onProviderOpen={ms.openProvider}
onSelect={ms.handleSelect}
sectionHeaderClass="px-2 py-2 text-xs font-semibold text-muted-foreground/60 select-none"
{showOrgName}
/>
</div>
@@ -222,7 +226,12 @@
>
<Package class="h-3.5 w-3.5 shrink-0" />
<ModelId class="font-medium" hideQuantization modelId={selectedOption?.model || ''} />
<ModelId
class="font-medium"
hideOrgName={!showOrgName}
hideQuantization
modelId={selectedOption?.model || ''}
/>
{#if ms.updating}
<Loader2 class="h-3 w-3.5 shrink-0 animate-spin" />
@@ -57,7 +57,7 @@ export const SETTINGS_KEYS = {
SHOW_FULL_PATH_IN_MENTIONS: 'showFullPathInMentions',
// Display
SHOW_MESSAGE_STATS: 'showMessageStats',
SHOW_MODEL_ORG_NAME_IN_TRIGGER: 'showModelOrgNameInTrigger',
SHOW_MODEL_ORG_NAME: 'showModelOrgName',
SHOW_MODEL_QUANTIZATION: 'showModelQuantization',
SHOW_MODEL_TAGS: 'showModelTags',
SHOW_RAW_MODEL_NAMES: 'showRawModelNames',
@@ -318,10 +318,10 @@ export const SETTINGS_REGISTRY: SettingsSectionEntry[] = [
type: SettingsFieldType.CHECKBOX
},
{
defaultValue: false,
help: 'Display the organization name in the model selector trigger button.',
key: SETTINGS_KEYS.SHOW_MODEL_ORG_NAME_IN_TRIGGER,
label: 'Show organization name in model selector trigger',
defaultValue: true,
help: 'Display the organization name alongside model names in the model selector, in the trigger and in the model rows.',
key: SETTINGS_KEYS.SHOW_MODEL_ORG_NAME,
label: 'Show organization name in model selector',
type: SettingsFieldType.CHECKBOX
},
{
@@ -220,6 +220,7 @@ class SettingsStore {
try {
this.loadConfig();
this.migrateLegacyTheme();
this.migrateModelOrgNameKey();
// Apply the persisted theme from config on initial load
setMode(this.config[SETTINGS_KEYS.THEME] as ColorMode);
this.isInitialized = true;
@@ -475,6 +476,30 @@ class SettingsStore {
}
}
/**
* Move the trigger-only org name key onto the selector wide one. The setting
* grew from the trigger to every model id, so an explicit choice has to
* survive the rename.
*/
private migrateModelOrgNameKey() {
if (!browser) return;
const legacyKey = 'showModelOrgNameInTrigger';
const { config: saved } = SettingsService.loadConfig();
if (!(legacyKey in saved)) return;
this.config[SETTINGS_KEYS.SHOW_MODEL_ORG_NAME] = Boolean(saved[legacyKey]);
if (this.userOverrides.delete(legacyKey)) {
this.userOverrides.add(SETTINGS_KEYS.SHOW_MODEL_ORG_NAME);
}
delete (this.config as Record<string, unknown>)[legacyKey];
this.saveConfig();
}
/**
* Save the current configuration to localStorage via the persistence service.
*/