ui : add sampling & penalties submenu to model selector

Assisted-by: pi
This commit is contained in:
Aleksander Grygier
2026-08-21 10:49:23 +02:00
committed by GitHub
parent 4fa82dc623
commit 7cf1e7f5f5
5 changed files with 112 additions and 69 deletions
@@ -0,0 +1,27 @@
<script lang="ts">
import ModelsSelectorSettingsFields from './ModelsSelectorSettingsFields.svelte';
import { Funnel } from '@lucide/svelte';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import type { SettingsSection } from '$lib/types';
interface Props {
section: SettingsSection;
disabled?: boolean;
}
let { disabled = false, section }: Props = $props();
</script>
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger class="flex cursor-pointer items-center gap-2" {disabled}>
<Funnel class="h-4 w-4 shrink-0 text-muted-foreground" />
<span class="text-sm text-muted-foreground">Sampling & Penalties</span>
</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent
class="max-h-96 w-72 overflow-y-auto bg-popover p-3 pt-2 text-popover-foreground shadow-md outline-none"
>
<ModelsSelectorSettingsFields {section} />
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
@@ -7,9 +7,9 @@
DialogModelInformation,
DropdownMenuSearchable,
ModelId,
ModelsSelectorAdvancedSubmenu,
ModelsSelectorList,
ModelsSelectorOption,
ModelsSelectorSettingsSubmenu
ModelsSelectorOption
} from '$lib/components/app';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Tooltip from '$lib/components/ui/tooltip';
@@ -368,7 +368,7 @@
<ChatFormActionAddReasoningSubmenu />
{#if samplingPenaltiesSection}
<ModelsSelectorSettingsSubmenu
<ModelsSelectorAdvancedSubmenu
section={samplingPenaltiesSection}
disabled={!hasModelLoaded}
/>
@@ -0,0 +1,78 @@
<script lang="ts">
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 type { SettingsSection } from '$lib/types';
import { normalizeFloatingPoint } from '$lib/utils/precision';
interface Props {
section: SettingsSection;
}
let { section }: Props = $props();
let currentModelParams = $derived.by(() => {
void modelsStore.props.cacheVersion;
if (serverStore.isRouterMode) {
const currentModelName = modelsStore.selectedModelName;
if (currentModelName) {
const currentModelProps = modelsStore.props.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>
<div class="grid gap-1">
{#each section.fields ?? [] as field (field.key)}
{#if field.type === SettingsFieldType.INPUT}
<label class="mb-2 flex flex-col gap-1.5">
<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}
</div>
@@ -1,11 +1,7 @@
<script lang="ts">
import { Checkbox } from '$lib/components/ui/checkbox';
import ModelsSelectorSettingsFields from './ModelsSelectorSettingsFields.svelte';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import { Input } from '$lib/components/ui/input';
import { SettingsFieldType } from '$lib/enums/settings.enums';
import { modelsStore, serverStore, settingsStore } from '$lib/stores';
import type { SettingsSection } from '$lib/types';
import { normalizeFloatingPoint } from '$lib/utils/precision';
interface Props {
section: SettingsSection;
@@ -13,41 +9,6 @@
}
let { disabled = false, section }: Props = $props();
let currentModelParams = $derived.by(() => {
void modelsStore.props.cacheVersion;
if (serverStore.isRouterMode) {
const currentModelName = modelsStore.selectedModelName;
if (currentModelName) {
const currentModelProps = modelsStore.props.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>
@@ -60,31 +21,6 @@
<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}
<ModelsSelectorSettingsFields {section} />
</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 ModelsSelectorAdvancedSubmenu } from './ModelsSelectorAdvancedSubmenu.svelte';
export { default as ModelsSelectorSettingsSubmenu } from './ModelsSelectorSettingsSubmenu.svelte';
/**