mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-29 17:37:39 -05:00
ui : route sidecar tag lookup through the sidecars util, validate the paused list
Assisted-by: pi:zai-org/GLM-5.3-Flash
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { base } from '$app/paths';
|
||||
import { API_MODELS, MODEL_ID, type ModelSidecar, SIDECAR_TOKENS } from '$lib/constants';
|
||||
import { API_MODELS, MODEL_ID, type ModelSidecar } from '$lib/constants';
|
||||
import { ServerModelStatus } from '$lib/enums';
|
||||
import type { ParsedModelId } from '$lib/types/models';
|
||||
import {
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
extractSseDataPayload,
|
||||
normalizeModelName,
|
||||
sidecarFromFileToken,
|
||||
sidecarFromTag,
|
||||
splitSseRecords
|
||||
} from '$lib/utils';
|
||||
import { getAuthHeaders } from '$lib/utils/api-headers';
|
||||
@@ -94,11 +95,7 @@ export class ModelsService {
|
||||
|
||||
if (idx === MODEL_ID.NOT_FOUND) return false;
|
||||
|
||||
const tag = modelId.slice(idx + 1).toLowerCase();
|
||||
const dash = tag.lastIndexOf(MODEL_ID.SEGMENT_SEPARATOR);
|
||||
const token = dash === -1 ? tag : tag.slice(dash + 1);
|
||||
|
||||
return SIDECAR_TOKENS.includes(token);
|
||||
return sidecarFromTag(modelId.slice(idx + 1)) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -169,8 +169,11 @@ export class ModelStatusManager {
|
||||
// localStorage; the progress snapshot is stale after a reload and stays null
|
||||
try {
|
||||
const raw = localStorage.getItem(PAUSED_MODEL_DOWNLOADS_LOCALSTORAGE_KEY);
|
||||
const parsed: unknown = JSON.parse(raw ?? '[]');
|
||||
|
||||
for (const repoWithTag of JSON.parse(raw ?? '[]') as string[]) {
|
||||
if (!Array.isArray(parsed)) return;
|
||||
|
||||
for (const repoWithTag of parsed.filter((id): id is string => typeof id === 'string')) {
|
||||
this.pausedDownloads.set(repoWithTag, null);
|
||||
}
|
||||
} catch {
|
||||
|
||||
@@ -108,7 +108,7 @@ export {
|
||||
export { normalizeModelName, isValidModelName } from './model-names';
|
||||
|
||||
// Sidecar token utilities
|
||||
export { isAuxSidecar, isDraftSidecar, sidecarFromFileToken } from './sidecars';
|
||||
export { isAuxSidecar, isDraftSidecar, sidecarFromFileToken, sidecarFromTag } from './sidecars';
|
||||
|
||||
// Portal utilities
|
||||
export { portalToBody } from './portal-to-body';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type ModelSidecar, SIDECAR_TOKENS } from '$lib/constants';
|
||||
import { MODEL_ID, type ModelSidecar, SIDECAR_TOKENS } from '$lib/constants';
|
||||
import { ModelAuxSidecar, ModelDraftSidecar } from '$lib/enums';
|
||||
|
||||
const SIDECAR_TOKEN_SET = new Set<string>(SIDECAR_TOKENS);
|
||||
@@ -10,6 +10,17 @@ export function sidecarFromFileToken(token: string): ModelSidecar | null {
|
||||
return SIDECAR_TOKEN_SET.has(token) ? (token as ModelSidecar) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sidecar a download tag points at: the segment after the last dash,
|
||||
* e.g. `q4_0-mtp` -> `mtp`, `mmproj` -> `mmproj`. Returns null for quant-only
|
||||
* tags and tags whose tail is not a sidecar token.
|
||||
*/
|
||||
export function sidecarFromTag(tag: string): ModelSidecar | null {
|
||||
const token = tag.toLowerCase().split(MODEL_ID.SEGMENT_SEPARATOR).pop() ?? '';
|
||||
|
||||
return sidecarFromFileToken(token);
|
||||
}
|
||||
|
||||
export function isDraftSidecar(sidecar: ModelSidecar): sidecar is ModelDraftSidecar {
|
||||
return DRAFT_SIDECAR_SET.has(sidecar);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ModelAuxSidecar, ModelDraftSidecar, SidecarForm } from '$lib/enums';
|
||||
import { HuggingFaceService } from '$lib/services/huggingface.service';
|
||||
import { ModelsService } from '$lib/services/models.service';
|
||||
import { sidecarFromTag } from '$lib/utils';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const { buildDownloadTag, isSidecarEntry } = ModelsService;
|
||||
@@ -125,3 +126,15 @@ describe('isSidecarEntry', () => {
|
||||
expect(isSidecarEntry('org/repo')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sidecarFromTag', () => {
|
||||
it('reads the token after the last dash', () => {
|
||||
expect(sidecarFromTag('Q4_0-mtp')).toBe(ModelDraftSidecar.MTP);
|
||||
expect(sidecarFromTag('mmproj')).toBe(ModelAuxSidecar.MMPROJ);
|
||||
});
|
||||
|
||||
it('returns null for quant-only and unrelated tags', () => {
|
||||
expect(sidecarFromTag('Q4_K_XL')).toBeNull();
|
||||
expect(sidecarFromTag('UD-Q4_K_XL')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user