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          7x   7x   7x                   28x 28x 26x         2381x 186x 186x 185x                     128x 52x 52x 24x         46x 46x 46x 46x 90x 90x 450x 450x 78x 78x       46x         1741x 636x 30x   606x 3601x   596x 8x   588x    
// 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. A multi-quant GGUF
 * repo (e.g. "bartowski/SmolLM2-360M-Instruct-GGUF") has no single default
 * file, so the server rejects the bare repo with "not available"; send the
 * concrete "<repo>/<filename>.gguf" instead. 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;
}