diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-02-12 20:57:17 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-02-12 20:57:17 +0100 |
| commit | b333b06772c89d96aacb5490d6a219fba7c09cc6 (patch) | |
| tree | 211df60083a5946baa2ed61d33d8121b7e251b06 /llama.cpp/tools/server/webui/src/lib/services/models.ts | |
| download | llmnpc-b333b06772c89d96aacb5490d6a219fba7c09cc6.tar.gz | |
Engage!
Diffstat (limited to 'llama.cpp/tools/server/webui/src/lib/services/models.ts')
| -rw-r--r-- | llama.cpp/tools/server/webui/src/lib/services/models.ts | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/llama.cpp/tools/server/webui/src/lib/services/models.ts b/llama.cpp/tools/server/webui/src/lib/services/models.ts new file mode 100644 index 0000000..eecb7fa --- /dev/null +++ b/llama.cpp/tools/server/webui/src/lib/services/models.ts | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | import { base } from '$app/paths'; | ||
| 2 | import { ServerModelStatus } from '$lib/enums'; | ||
| 3 | import { getJsonHeaders } from '$lib/utils'; | ||
| 4 | |||
| 5 | /** | ||
| 6 | * ModelsService - Stateless service for model management API communication | ||
| 7 | * | ||
| 8 | * This service handles communication with model-related endpoints: | ||
| 9 | * - `/v1/models` - OpenAI-compatible model list (MODEL + ROUTER mode) | ||
| 10 | * - `/models/load`, `/models/unload` - Router-specific model management (ROUTER mode only) | ||
| 11 | * | ||
| 12 | * **Responsibilities:** | ||
| 13 | * - List available models | ||
| 14 | * - Load/unload models (ROUTER mode) | ||
| 15 | * - Check model status (ROUTER mode) | ||
| 16 | * | ||
| 17 | * **Used by:** | ||
| 18 | * - modelsStore: Primary consumer for model state management | ||
| 19 | */ | ||
| 20 | export class ModelsService { | ||
| 21 | // ───────────────────────────────────────────────────────────────────────────── | ||
| 22 | // Listing | ||
| 23 | // ───────────────────────────────────────────────────────────────────────────── | ||
| 24 | |||
| 25 | /** | ||
| 26 | * Fetch list of models from OpenAI-compatible endpoint | ||
| 27 | * Works in both MODEL and ROUTER modes | ||
| 28 | */ | ||
| 29 | static async list(): Promise<ApiModelListResponse> { | ||
| 30 | const response = await fetch(`${base}/v1/models`, { | ||
| 31 | headers: getJsonHeaders() | ||
| 32 | }); | ||
| 33 | |||
| 34 | if (!response.ok) { | ||
| 35 | throw new Error(`Failed to fetch model list (status ${response.status})`); | ||
| 36 | } | ||
| 37 | |||
| 38 | return response.json() as Promise<ApiModelListResponse>; | ||
| 39 | } | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Fetch list of all models with detailed metadata (ROUTER mode) | ||
| 43 | * Returns models with load status, paths, and other metadata | ||
| 44 | */ | ||
| 45 | static async listRouter(): Promise<ApiRouterModelsListResponse> { | ||
| 46 | const response = await fetch(`${base}/v1/models`, { | ||
| 47 | headers: getJsonHeaders() | ||
| 48 | }); | ||
| 49 | |||
| 50 | if (!response.ok) { | ||
| 51 | throw new Error(`Failed to fetch router models list (status ${response.status})`); | ||
| 52 | } | ||
| 53 | |||
| 54 | return response.json() as Promise<ApiRouterModelsListResponse>; | ||
| 55 | } | ||
| 56 | |||
| 57 | // ───────────────────────────────────────────────────────────────────────────── | ||
| 58 | // Load/Unload | ||
| 59 | // ───────────────────────────────────────────────────────────────────────────── | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Load a model (ROUTER mode) | ||
| 63 | * POST /models/load | ||
| 64 | * @param modelId - Model identifier to load | ||
| 65 | * @param extraArgs - Optional additional arguments to pass to the model instance | ||
| 66 | */ | ||
| 67 | static async load(modelId: string, extraArgs?: string[]): Promise<ApiRouterModelsLoadResponse> { | ||
| 68 | const payload: { model: string; extra_args?: string[] } = { model: modelId }; | ||
| 69 | if (extraArgs && extraArgs.length > 0) { | ||
| 70 | payload.extra_args = extraArgs; | ||
| 71 | } | ||
| 72 | |||
| 73 | const response = await fetch(`${base}/models/load`, { | ||
| 74 | method: 'POST', | ||
| 75 | headers: getJsonHeaders(), | ||
| 76 | body: JSON.stringify(payload) | ||
| 77 | }); | ||
| 78 | |||
| 79 | if (!response.ok) { | ||
| 80 | const errorData = await response.json().catch(() => ({})); | ||
| 81 | throw new Error(errorData.error || `Failed to load model (status ${response.status})`); | ||
| 82 | } | ||
| 83 | |||
| 84 | return response.json() as Promise<ApiRouterModelsLoadResponse>; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Unload a model (ROUTER mode) | ||
| 89 | * POST /models/unload | ||
| 90 | * @param modelId - Model identifier to unload | ||
| 91 | */ | ||
| 92 | static async unload(modelId: string): Promise<ApiRouterModelsUnloadResponse> { | ||
| 93 | const response = await fetch(`${base}/models/unload`, { | ||
| 94 | method: 'POST', | ||
| 95 | headers: getJsonHeaders(), | ||
| 96 | body: JSON.stringify({ model: modelId }) | ||
| 97 | }); | ||
| 98 | |||
| 99 | if (!response.ok) { | ||
| 100 | const errorData = await response.json().catch(() => ({})); | ||
| 101 | throw new Error(errorData.error || `Failed to unload model (status ${response.status})`); | ||
| 102 | } | ||
| 103 | |||
| 104 | return response.json() as Promise<ApiRouterModelsUnloadResponse>; | ||
| 105 | } | ||
| 106 | |||
| 107 | // ───────────────────────────────────────────────────────────────────────────── | ||
| 108 | // Status | ||
| 109 | // ───────────────────────────────────────────────────────────────────────────── | ||
| 110 | |||
| 111 | /** | ||
| 112 | * Check if a model is loaded based on its metadata | ||
| 113 | */ | ||
| 114 | static isModelLoaded(model: ApiModelDataEntry): boolean { | ||
| 115 | return model.status.value === ServerModelStatus.LOADED; | ||
| 116 | } | ||
| 117 | |||
| 118 | /** | ||
| 119 | * Check if a model is currently loading | ||
| 120 | */ | ||
| 121 | static isModelLoading(model: ApiModelDataEntry): boolean { | ||
| 122 | return model.status.value === ServerModelStatus.LOADING; | ||
| 123 | } | ||
| 124 | } | ||
