mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-10-11 07:20:33 +02:00
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:
+19
-4
@@ -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}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user