Add SLEEPING status to the WebUI model selector (#20949)

* webui: handle sleeping model status, fix favourite -> favorite

* Update tools/server/webui/src/lib/components/app/models/ModelsSelectorOption.svelte

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* Update tools/server/webui/src/lib/components/app/models/ModelsSelectorOption.svelte

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* webui: fix optional event parameter in sleeping model onclick

* typo

* webui: restore orange sleeping indicator dot with hover unload

* chore: update webui build output

* webui: move stopPropagation into ActionIcon onclick, remove svelte-ignore

* chore: update webui build output

* webui: fix favourite -> favorite (UK -> US spelling) everywhere

Address review feedback from WhyNotHugo

* chore: update webui build output

---------

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
This commit is contained in:
Pascal
2026-03-25 11:02:32 +01:00
committed by GitHub
parent 406f4e3f61
commit 062cca58fc
11 changed files with 70 additions and 41 deletions
@@ -7,7 +7,7 @@ import { TTLCache } from '$lib/utils';
import {
MODEL_PROPS_CACHE_TTL_MS,
MODEL_PROPS_CACHE_MAX_ENTRIES,
FAVOURITE_MODELS_LOCALSTORAGE_KEY
FAVORITE_MODELS_LOCALSTORAGE_KEY
} from '$lib/constants';
/**
@@ -57,7 +57,7 @@ class ModelsStore {
private modelUsage = $state<Map<string, SvelteSet<string>>>(new Map());
private modelLoadingStates = new SvelteMap<string, boolean>();
favouriteModelIds = $state<Set<string>>(this.loadFavouritesFromStorage());
favoriteModelIds = $state<Set<string>>(this.loadFavoritesFromStorage());
/**
* Model-specific props cache with TTL
@@ -90,7 +90,11 @@ class ModelsStore {
get loadedModelIds(): string[] {
return this.routerModels
.filter((m) => m.status.value === ServerModelStatus.LOADED)
.filter(
(m) =>
m.status.value === ServerModelStatus.LOADED ||
m.status.value === ServerModelStatus.SLEEPING
)
.map((m) => m.id);
}
@@ -215,7 +219,11 @@ class ModelsStore {
isModelLoaded(modelId: string): boolean {
const model = this.routerModels.find((m) => m.id === modelId);
return model?.status.value === ServerModelStatus.LOADED || false;
return (
model?.status.value === ServerModelStatus.LOADED ||
model?.status.value === ServerModelStatus.SLEEPING ||
false
);
}
isModelOperationInProgress(modelId: string): boolean {
@@ -621,17 +629,17 @@ class ModelsStore {
/**
*
*
* Favourites
* Favorites
*
*
*/
isFavourite(modelId: string): boolean {
return this.favouriteModelIds.has(modelId);
isFavorite(modelId: string): boolean {
return this.favoriteModelIds.has(modelId);
}
toggleFavourite(modelId: string): void {
const next = new SvelteSet(this.favouriteModelIds);
toggleFavorite(modelId: string): void {
const next = new SvelteSet(this.favoriteModelIds);
if (next.has(modelId)) {
next.delete(modelId);
@@ -639,22 +647,22 @@ class ModelsStore {
next.add(modelId);
}
this.favouriteModelIds = next;
this.favoriteModelIds = next;
try {
localStorage.setItem(FAVOURITE_MODELS_LOCALSTORAGE_KEY, JSON.stringify([...next]));
localStorage.setItem(FAVORITE_MODELS_LOCALSTORAGE_KEY, JSON.stringify([...next]));
} catch {
toast.error('Failed to save favourite models to local storage');
toast.error('Failed to save favorite models to local storage');
}
}
private loadFavouritesFromStorage(): Set<string> {
private loadFavoritesFromStorage(): Set<string> {
try {
const raw = localStorage.getItem(FAVOURITE_MODELS_LOCALSTORAGE_KEY);
const raw = localStorage.getItem(FAVORITE_MODELS_LOCALSTORAGE_KEY);
return raw ? new Set(JSON.parse(raw) as string[]) : new Set();
} catch {
toast.error('Failed to load favourite models from local storage');
toast.error('Failed to load favorite models from local storage');
return new Set();
}
@@ -713,4 +721,4 @@ export const loadingModelIds = () => modelsStore.loadingModelIds;
export const propsCacheVersion = () => modelsStore.propsCacheVersion;
export const singleModelName = () => modelsStore.singleModelName;
export const selectedModelContextSize = () => modelsStore.selectedModelContextSize;
export const favouriteModelIds = () => modelsStore.favouriteModelIds;
export const favoriteModelIds = () => modelsStore.favoriteModelIds;