mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-19 01:04:55 +02:00
ui : extract the model params badge fallback into a hook
Move the option's fallback logic into useModelParamsFallback and reuse it for the dropdown and sheet trigger badges. Assisted-by: pi:zai-org/GLM-5.3
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
import * as Tooltip from '$lib/components/ui/tooltip';
|
||||
import { MODEL_SELECTOR_ICON, SETTINGS_KEYS } from '$lib/constants';
|
||||
import { KeyboardKey, ServerModelStatus } from '$lib/enums';
|
||||
import { useModelParamsFallback } from '$lib/hooks/use-model-params-fallback.svelte';
|
||||
import { useModelsSelector } from '$lib/hooks/use-models-selector.svelte';
|
||||
import { useReasoningMenu } from '$lib/hooks/use-reasoning-menu.svelte';
|
||||
import { modelsStore, settingsStore } from '$lib/stores';
|
||||
@@ -65,6 +66,15 @@
|
||||
|
||||
const reasoning = useReasoningMenu();
|
||||
|
||||
const selectedOption = $derived(ms.getDisplayOption());
|
||||
const triggerModel = $derived(selectedOption?.model ?? null);
|
||||
|
||||
// Params badge fallback for trigger ids that carry no params token.
|
||||
const { paramsFallback } = useModelParamsFallback({
|
||||
modelId: () => triggerModel,
|
||||
metaParams: () => selectedOption?.meta?.n_params
|
||||
});
|
||||
|
||||
const showOrgNameInTrigger = $derived(
|
||||
settingsStore.config[SETTINGS_KEYS.SHOW_MODEL_ORG_NAME_IN_TRIGGER] ?? false
|
||||
);
|
||||
@@ -179,8 +189,6 @@
|
||||
<p class="text-xs text-muted-foreground">No models available.</p>
|
||||
{/if}
|
||||
{:else}
|
||||
{@const selectedOption = ms.getDisplayOption()}
|
||||
{@const triggerModel = selectedOption?.model}
|
||||
{@const triggerStatus = triggerModel
|
||||
? modelsStore.routerModels.find((m) => m.id === triggerModel)?.status?.value
|
||||
: undefined}
|
||||
@@ -223,6 +231,7 @@
|
||||
hideOrgName={!showOrgNameInTrigger}
|
||||
hideQuantization
|
||||
modelId={selectedOption.model}
|
||||
params={paramsFallback}
|
||||
/>
|
||||
{:else}
|
||||
<span class="min-w-0 font-medium">Select model</span>
|
||||
@@ -331,7 +340,6 @@
|
||||
Sticks to the bottom of the content scrollport. -->
|
||||
<div onfocusin={clearHighlight} onmouseenter={clearHighlight} role="none">
|
||||
<ModelsSelectorReasoningPanel />
|
||||
|
||||
</div>
|
||||
{/snippet}
|
||||
</DropdownMenuSearchable>
|
||||
@@ -367,6 +375,7 @@
|
||||
hideOrgName={!showOrgNameInTrigger}
|
||||
hideQuantization
|
||||
modelId={selectedOption.model}
|
||||
params={paramsFallback}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -12,22 +12,13 @@
|
||||
RotateCw
|
||||
} from '@lucide/svelte';
|
||||
import { ActionIcon, ModelId } from '$lib/components/app';
|
||||
import {
|
||||
HF_BASE_MODEL_TAG_REGEX,
|
||||
ICON_CLASS_DEFAULT,
|
||||
MODEL_ID,
|
||||
PATH_SEPARATOR
|
||||
} from '$lib/constants';
|
||||
import { HF_BASE_MODEL_TAG_REGEX, ICON_CLASS_DEFAULT, PATH_SEPARATOR } from '$lib/constants';
|
||||
import { ModelCapability, ServerModelStatus } from '$lib/enums';
|
||||
import { HuggingFaceService, ModelsService } from '$lib/services';
|
||||
import { useModelParamsFallback } from '$lib/hooks/use-model-params-fallback.svelte';
|
||||
import { modelsStore } from '$lib/stores';
|
||||
import type { ModelOption } from '$lib/types/models';
|
||||
import {
|
||||
formatParameters,
|
||||
modelLoadFraction,
|
||||
modelLoadProgressText,
|
||||
normalizeModelName
|
||||
} from '$lib/utils';
|
||||
import { modelLoadFraction, modelLoadProgressText } from '$lib/utils';
|
||||
|
||||
interface Props {
|
||||
option: ModelOption;
|
||||
@@ -109,47 +100,10 @@
|
||||
tools: option.capabilities.includes(ModelCapability.TOOL_USE)
|
||||
}));
|
||||
|
||||
// Params badge fallback: the id usually carries the count (`Qwen3-8B`), but
|
||||
// ids like `Kimi-K3` do not. Prefer the loaded model's meta `n_params`, then
|
||||
// the HF GGUF total (`gguf.total`), fetched lazily like the models hub list
|
||||
// does, only when neither the id nor the meta has it.
|
||||
let parsedParams = $derived(parsedId.params);
|
||||
let metaParams = $derived.by(() => {
|
||||
const value = option.meta?.n_params;
|
||||
|
||||
return typeof value === 'number' && value > 0 ? value : null;
|
||||
const { paramsFallback } = useModelParamsFallback({
|
||||
modelId: () => option.model,
|
||||
metaParams: () => option.meta?.n_params
|
||||
});
|
||||
// HF repo id: the `org/model` part without the `:revision/quant` suffix;
|
||||
// local paths and bare names are not HF repos.
|
||||
let hfRepoId = $derived.by(() => {
|
||||
const [repo] = option.model.split(MODEL_ID.QUANTIZATION_SEPARATOR);
|
||||
const normalized = normalizeModelName(repo ?? '');
|
||||
|
||||
return normalized.includes(MODEL_ID.ORG_SEPARATOR) ? normalized : null;
|
||||
});
|
||||
let fetchedParams = $state<number | null>(null);
|
||||
|
||||
$effect(() => {
|
||||
fetchedParams = null;
|
||||
|
||||
if (parsedParams || metaParams || !hfRepoId) return;
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
void HuggingFaceService.getDetails(hfRepoId).then((info) => {
|
||||
if (!cancelled && info?.gguf?.total) fetchedParams = info.gguf.total;
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
});
|
||||
|
||||
let paramsFallback = $derived(
|
||||
!parsedParams && (metaParams ?? fetchedParams)
|
||||
? formatParameters(metaParams ?? fetchedParams)
|
||||
: undefined
|
||||
);
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
} from '$lib/components/app';
|
||||
import * as Sheet from '$lib/components/ui/sheet';
|
||||
import { ServerModelStatus } from '$lib/enums';
|
||||
import { useModelParamsFallback } from '$lib/hooks/use-model-params-fallback.svelte';
|
||||
import { useModelsSelector } from '$lib/hooks/use-models-selector.svelte';
|
||||
import { modelsStore } from '$lib/stores';
|
||||
import { modelLoadFraction } from '$lib/utils';
|
||||
@@ -44,6 +45,15 @@
|
||||
useGlobalSelection: () => useGlobalSelection
|
||||
});
|
||||
|
||||
const selectedOption = $derived(ms.getDisplayOption());
|
||||
const triggerModel = $derived(selectedOption?.model ?? null);
|
||||
|
||||
// Params badge fallback for trigger ids that carry no params token.
|
||||
const { paramsFallback } = useModelParamsFallback({
|
||||
metaParams: () => selectedOption?.meta?.n_params,
|
||||
modelId: () => triggerModel
|
||||
});
|
||||
|
||||
export function open() {
|
||||
ms.handleOpenChange(true);
|
||||
}
|
||||
@@ -106,6 +116,7 @@
|
||||
hideQuantization
|
||||
hideTags
|
||||
modelId={selectedOption?.model || ''}
|
||||
params={paramsFallback}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -190,7 +201,12 @@
|
||||
>
|
||||
<Package class="h-3.5 w-3.5 shrink-0" />
|
||||
|
||||
<ModelId class="font-medium" hideQuantization modelId={selectedOption?.model || ''} />
|
||||
<ModelId
|
||||
class="font-medium"
|
||||
hideQuantization
|
||||
modelId={selectedOption?.model || ''}
|
||||
params={paramsFallback}
|
||||
/>
|
||||
|
||||
{#if ms.updating}
|
||||
<Loader2 class="h-3 w-3.5 shrink-0 animate-spin" />
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { MODEL_ID } from '$lib/constants';
|
||||
import { HuggingFaceService, ModelsService } from '$lib/services';
|
||||
import { formatParameters, normalizeModelName } from '$lib/utils';
|
||||
|
||||
export interface UseModelParamsFallbackOptions {
|
||||
/** Model id to parse; null disables the fallback. */
|
||||
modelId: () => string | null | undefined;
|
||||
/** Server-reported parameter count from the model meta, when available. */
|
||||
metaParams?: () => unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Params badge fallback for model ids that carry no params token (`Kimi-K3`).
|
||||
* Prefers the meta `n_params`, then the HF GGUF total (`gguf.total`) fetched
|
||||
* lazily like the models hub list does, only when neither the id nor the meta
|
||||
* has it. Returns the formatted badge text, or undefined when unavailable.
|
||||
*/
|
||||
export function useModelParamsFallback(opts: UseModelParamsFallbackOptions) {
|
||||
const parsedParams = $derived.by(() => {
|
||||
const id = opts.modelId();
|
||||
|
||||
return id ? ModelsService.parseModelId(id).params : null;
|
||||
});
|
||||
const metaParams = $derived.by(() => {
|
||||
const value = opts.metaParams?.();
|
||||
|
||||
return typeof value === 'number' && value > 0 ? value : null;
|
||||
});
|
||||
// HF repo id: the `org/model` part without the `:revision/quant` suffix;
|
||||
// local paths and bare names are not HF repos.
|
||||
const hfRepoId = $derived.by(() => {
|
||||
const id = opts.modelId();
|
||||
|
||||
if (!id) return null;
|
||||
|
||||
const [repo] = id.split(MODEL_ID.QUANTIZATION_SEPARATOR);
|
||||
const normalized = normalizeModelName(repo ?? '');
|
||||
|
||||
return normalized.includes(MODEL_ID.ORG_SEPARATOR) ? normalized : null;
|
||||
});
|
||||
let fetchedParams = $state<number | null>(null);
|
||||
|
||||
$effect(() => {
|
||||
fetchedParams = null;
|
||||
|
||||
if (parsedParams || metaParams || !hfRepoId) return;
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
void HuggingFaceService.getDetails(hfRepoId).then((info) => {
|
||||
if (!cancelled && info?.gguf?.total) fetchedParams = info.gguf.total;
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
});
|
||||
|
||||
const paramsFallback = $derived(
|
||||
!parsedParams && (metaParams ?? fetchedParams)
|
||||
? formatParameters(metaParams ?? fetchedParams)
|
||||
: undefined
|
||||
);
|
||||
|
||||
return { paramsFallback };
|
||||
}
|
||||
Reference in New Issue
Block a user