ui : keep the table status working while a provider is active

The status cell branched on the active backend's role, so rows collapsed
to the served-by placeholder once a provider was the selected backend,
and the state lookup resolved the backend by raw-name first match, which
a same-named provider catalog entry shadowed: loading a loaded local
model then failed with 'model is already running'.

Branch the cell per row instead, resolve the state from the local feed
first and the backends' own listings after, and start the local feed
while a remote backend is active: the feed reports the local server's
models, so the local server's role decides.

Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
Aleksander Grygier
2026-10-09 11:09:40 +02:00
committed by GitHub
parent b12917cfbc
commit c0f7c7e60d
3 changed files with 38 additions and 16 deletions
@@ -2,6 +2,7 @@
import ModelLoadControl from '../ModelLoadControl.svelte';
import ModelsManagerDownloadControl from './ModelsManagerDownloadControl.svelte';
import { canLoadOption } from './utils';
import { LOCAL_BACKEND_ID } from '$lib/constants';
import type { ModelRowDownloadState } from '$lib/enums';
import { ServerModelStatus } from '$lib/enums';
import { modelsStore, serverStore } from '$lib/stores';
@@ -19,21 +20,35 @@
let status = $derived(modelsStore.getModelStatus(option.model));
let isOperationInProgress = $derived(modelsStore.status.isOperationInProgress(option.model));
let isLoaded = $derived(modelsStore.isModelRunning(option.model));
// a MODEL server serves the model it was started with and answers no load route
let isRouter = $derived(serverStore.isRouterMode);
// a llama-compat row loads through its own server: the local one takes load
// requests in router mode only, whatever backend is active, and a provider
// row never reports a load state
let canToggleLoad = $derived(
canLoadOption(option) &&
(!option.backendId || option.backendId === LOCAL_BACKEND_ID
? serverStore.localIsRouter
: true)
);
</script>
{#if download}
<ModelsManagerDownloadControl class="justify-self-center {className}" {option} state={download} />
{:else if isRouter}
{:else if canToggleLoad}
<ModelLoadControl
canLoad={canLoadOption(option)}
canLoad
class="justify-self-center {className}"
isFailed={status === ServerModelStatus.FAILED}
{isLoaded}
isLoading={status === ServerModelStatus.LOADING || isOperationInProgress}
isSleeping={status === ServerModelStatus.SLEEPING}
{option}
/>
{:else if option.backendId && option.backendId !== LOCAL_BACKEND_ID}
<ModelLoadControl
canLoad={false}
class="justify-self-center {className}"
isLoaded={false}
{option}
showRemoteMark
/>
{:else}
+13 -10
View File
@@ -12,7 +12,6 @@ import {
BackendProtocol,
FAVORITE_MODELS_LOCALSTORAGE_KEY,
HIDDEN_MODELS_LOCALSTORAGE_KEY,
LOCAL_BACKEND_ID,
MODEL_GROUP_OPEN_LOCALSTORAGE_KEY,
RECENT_MODEL_LIMIT,
RECENT_MODELS_LOCALSTORAGE_KEY,
@@ -461,17 +460,21 @@ class ModelsStore implements ModelPropsHost, ModelStatusHost {
* feed, so an external backend answers from its own model listing.
*/
getModelStatus(modelId: string): ServerModelStatus | null {
const backendId = this.models.find((model) => model.model === modelId)?.backendId;
if (backendId && backendId !== LOCAL_BACKEND_ID) {
const option = backendsModelsStore.get(backendId).models.find((m) => m.model === modelId);
return (option?.status?.value as ServerModelStatus) ?? null;
}
// the local feed reports the models its router serves: a same-named entry
// on a remote provider must not shadow it
const model = this.routerModels.find((m) => m.id === modelId);
return (model?.status?.value as ServerModelStatus) ?? null;
if (model) return (model.status?.value as ServerModelStatus) ?? null;
// a model the local router does not serve belongs to a backend, and the
// first enabled backend listing it owns the state
for (const backend of backendsStore.enabled) {
const option = backendsModelsStore.get(backend.id).models.find((m) => m.model === modelId);
if (option) return (option.status?.value as ServerModelStatus) ?? null;
}
return null;
}
hasModel(modelName: string): boolean {
@@ -232,7 +232,9 @@ export class ModelStatusManager {
async cancelLoad(modelId: string): Promise<void> {
const backendId = this.backendIdFor(modelId);
if (!serverStore.isRouterMode) return;
// the local server takes unload requests in router mode only; a remote
// backend cancels on its own
if (backendId === LOCAL_BACKEND_ID && !serverStore.localIsRouter) return;
this.subscribe();
@@ -478,7 +480,9 @@ export class ModelStatusManager {
subscribe(): void {
if (this.statusReaderActive) return;
if (!serverStore.isRouterMode) return;
// the feed reports the local server's models, so the local server's role
// decides, not the active backend's
if (!serverStore.localIsRouter) return;
this.statusReaderActive = true;
this.statusAbort = new AbortController();