mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-19 17:24:57 +02:00
ui : add sampling and penalties submenus to model selector
Add reusable ModelsSelectorSettingsSubmenu that renders a settings section's fields as inline editable inputs bound to settingsStore. Wire it into the model selector dropdown for the Sampling and Penalties sections, showing server defaults as placeholders and disabling the submenus until a model is loaded.
This commit is contained in:
@@ -8,11 +8,17 @@
|
||||
DropdownMenuSearchable,
|
||||
ModelId,
|
||||
ModelsSelectorList,
|
||||
ModelsSelectorOption
|
||||
ModelsSelectorOption,
|
||||
ModelsSelectorSettingsSubmenu
|
||||
} from '$lib/components/app';
|
||||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip';
|
||||
import { MODEL_SELECTOR_ICON, SETTINGS_KEYS } from '$lib/constants';
|
||||
import {
|
||||
MODEL_SELECTOR_ICON,
|
||||
SETTINGS_CHAT_SECTIONS,
|
||||
SETTINGS_KEYS,
|
||||
SETTINGS_SECTION_SLUGS
|
||||
} from '$lib/constants';
|
||||
import { KeyboardKey, ServerModelStatus } from '$lib/enums';
|
||||
import { useModelsSelector } from '$lib/hooks/use-models-selector.svelte';
|
||||
import { useReasoningMenu } from '$lib/hooks/use-reasoning-menu.svelte';
|
||||
@@ -66,6 +72,17 @@
|
||||
|
||||
const reasoning = useReasoningMenu();
|
||||
|
||||
const samplingSection = $derived(
|
||||
SETTINGS_CHAT_SECTIONS.find((s) => s.slug === SETTINGS_SECTION_SLUGS.SAMPLING)
|
||||
);
|
||||
const penaltiesSection = $derived(
|
||||
SETTINGS_CHAT_SECTIONS.find((s) => s.slug === SETTINGS_SECTION_SLUGS.PENALTIES)
|
||||
);
|
||||
|
||||
// Sampling/penalties need a loaded model to show server defaults, so
|
||||
// disable the submenus until one is loaded.
|
||||
const hasModelLoaded = $derived(modelsStore.loadedModelIds.length > 0);
|
||||
|
||||
const showOrgNameInTrigger = $derived(
|
||||
settingsStore.config[SETTINGS_KEYS.SHOW_MODEL_ORG_NAME_IN_TRIGGER] ?? false
|
||||
);
|
||||
@@ -352,6 +369,14 @@
|
||||
</DropdownMenu.Sub>
|
||||
|
||||
<ChatFormActionAddReasoningSubmenu />
|
||||
|
||||
{#if samplingSection}
|
||||
<ModelsSelectorSettingsSubmenu section={samplingSection} disabled={!hasModelLoaded} />
|
||||
{/if}
|
||||
|
||||
{#if penaltiesSection}
|
||||
<ModelsSelectorSettingsSubmenu section={penaltiesSection} disabled={!hasModelLoaded} />
|
||||
{/if}
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Root>
|
||||
{:else}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<script lang="ts">
|
||||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
import { SettingsFieldType } from '$lib/enums/settings.enums';
|
||||
import { modelsStore, serverStore, settingsStore } from '$lib/stores';
|
||||
import { normalizeFloatingPoint } from '$lib/utils/precision';
|
||||
import type { SettingsSection } from '$lib/types';
|
||||
|
||||
interface Props {
|
||||
section: SettingsSection;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
let { section, disabled = false }: Props = $props();
|
||||
|
||||
let currentModelParams = $derived.by(() => {
|
||||
void modelsStore.propsCacheVersion;
|
||||
|
||||
if (serverStore.isRouterMode) {
|
||||
const currentModelName = modelsStore.selectedModelName;
|
||||
|
||||
if (currentModelName) {
|
||||
const currentModelProps = modelsStore.getModelProps(currentModelName);
|
||||
|
||||
return (currentModelProps?.default_generation_settings?.params ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
}
|
||||
}
|
||||
|
||||
return (serverStore.defaultParams ?? {}) as Record<string, unknown>;
|
||||
});
|
||||
|
||||
function currentValue(key: string): string {
|
||||
const value = settingsStore.config[key];
|
||||
|
||||
return value == null ? '' : String(value);
|
||||
}
|
||||
|
||||
function handleInput(key: string, value: string) {
|
||||
settingsStore.updateConfig(key, value);
|
||||
}
|
||||
|
||||
function placeholder(key: string): string {
|
||||
const serverDefault = currentModelParams[key];
|
||||
|
||||
return serverDefault != null ? `Default: ${normalizeFloatingPoint(serverDefault)}` : '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
disabled={disabled}
|
||||
>
|
||||
<section.icon class="h-4 w-4 shrink-0 text-muted-foreground" />
|
||||
|
||||
<span class="text-sm text-muted-foreground">{section.title}</span>
|
||||
</DropdownMenu.SubTrigger>
|
||||
|
||||
<DropdownMenu.SubContent
|
||||
class="max-h-96 w-72 overflow-y-auto bg-popover p-2 text-popover-foreground shadow-md outline-none"
|
||||
>
|
||||
{#each section.fields ?? [] as field (field.key)}
|
||||
{#if field.type === SettingsFieldType.INPUT}
|
||||
<label class="mb-2 flex flex-col gap-1">
|
||||
<span class="text-xs font-medium text-muted-foreground">{field.label}</span>
|
||||
|
||||
<Input
|
||||
type="text"
|
||||
value={currentValue(field.key)}
|
||||
placeholder={placeholder(field.key)}
|
||||
oninput={(event) => handleInput(field.key, event.currentTarget.value)}
|
||||
class="h-8"
|
||||
/>
|
||||
</label>
|
||||
{:else if field.type === SettingsFieldType.CHECKBOX}
|
||||
<label class="flex cursor-pointer items-center gap-2 rounded-md px-1 py-1.5 text-sm hover:bg-accent">
|
||||
<Checkbox
|
||||
checked={Boolean(settingsStore.config[field.key])}
|
||||
onCheckedChange={(checked) => settingsStore.updateConfig(field.key, Boolean(checked))}
|
||||
/>
|
||||
|
||||
<span>{field.label}</span>
|
||||
</label>
|
||||
{/if}
|
||||
{/each}
|
||||
</DropdownMenu.SubContent>
|
||||
</DropdownMenu.Sub>
|
||||
@@ -65,6 +65,8 @@ export { default as ModelsSelectorList } from './ModelsSelectorList.svelte';
|
||||
*/
|
||||
export { default as ModelsSelectorOption } from './ModelsSelectorOption.svelte';
|
||||
|
||||
export { default as ModelsSelectorSettingsSubmenu } from './ModelsSelectorSettingsSubmenu.svelte';
|
||||
|
||||
/**
|
||||
* **ModelsSelectorSheet** - Mobile model selection sheet
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user