All files / src/utils model-ref.ts

100% Statements 40/40
100% Branches 29/29
100% Functions 5/5
100% Lines 33/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79          12x   12x   12x                   104x 104x 98x         7279x 251x 251x 250x                     209x 79x 79x 51x         72x 72x 72x 72x 120x 120x 600x 600x 84x 84x       72x         3758x 2045x 33x   2012x 12037x   2002x 31x   1971x    
// Helpers for the canonical model ref shape lilbee speaks. Refs come in three
// flavours: native HF refs ("<org>/<repo>/<filename>.gguf"), provider refs
// ("ollama/qwen3:8b", "openai/gpt-4o", …), and opaque strings. The helpers
// below convert them for display or unwrap them for catalog comparison.
 
const PROVIDER_PREFIXES = ["ollama/", "lm_studio/", "openai/", "anthropic/", "gemini/", "cohere/"];
 
const STRIP_SUFFIXES = [/-GGUF$/i, /-Instruct$/i, /-Chat$/i, /-v\d+(\.\d+)*$/i, /-\d{4}$/];
 
const META_PREFIX = /^Meta-/;
 
/**
 * Build the ref to send when activating a catalog entry. The server resolves a
 * bare multi-quant repo by taking the first installed quant in sort order, so
 * sending "<repo>/<filename>.gguf" is what makes the user's choice exact.
 * Falls back to the bare repo when the filename is missing or a glob
 * (sharded/pattern entries).
 */
export function nativeModelRef(hfRepo: string, ggufFilename: string | null | undefined): string {
    const f = ggufFilename ?? "";
    if (f && f.endsWith(".gguf") && !f.includes("*")) return `${hfRepo}/${f}`;
    return hfRepo;
}
 
/** Strip the trailing `/<filename>.gguf` from a full HF ref so it matches a `CatalogEntry.hf_repo`. */
export function extractHfRepo(ref: string): string {
    if (!ref.endsWith(".gguf")) return ref;
    const slash = ref.lastIndexOf("/");
    if (slash <= 0) return ref;
    return ref.slice(0, slash);
}
 
/**
 * The dropdown option value that represents `active`. Server config stores a full
 * native ref (`<repo>/<file>.gguf`) but installed-featured options key on the bare
 * `hf_repo`, so an exact lookup misses and the dropdown renders blank. Match exactly
 * first (hosted refs, other-installed full refs), then by bare repo; fall back to the
 * ref unchanged when nothing matches.
 */
export function matchModelOption(active: string, optionValues: string[]): string {
    if (optionValues.includes(active)) return active;
    const repo = extractHfRepo(active);
    if (optionValues.includes(repo)) return repo;
    return active;
}
 
/** Convert a `<repo>` segment (org-stripped) into a friendly label. Mirrors the server's `clean_display_name`. */
export function cleanDisplayName(repo: string): string {
    let name = repo.includes("/") ? repo.slice(repo.indexOf("/") + 1) : repo;
    name = name.replace(META_PREFIX, "");
    let changed = true;
    while (changed) {
        changed = false;
        for (const suffix of STRIP_SUFFIXES) {
            const next = name.replace(suffix, "");
            if (next !== name) {
                name = next;
                changed = true;
            }
        }
    }
    return name.replace(/-/g, " ").replace(/\s+/g, " ").trim();
}
 
/** Turn any model ref into a label suitable for the status bar, dropdowns, and notices. */
export function displayLabelForRef(ref: string): string {
    if (!ref) return "";
    if (ref.endsWith(".gguf") && ref.includes("/")) {
        return cleanDisplayName(extractHfRepo(ref));
    }
    for (const prefix of PROVIDER_PREFIXES) {
        if (ref.startsWith(prefix)) return ref.slice(prefix.length);
    }
    if (ref.includes("/")) {
        return cleanDisplayName(ref);
    }
    return ref;
}