Consolidate the tests without changing what they prove

Test-only. No file under studio/frontend/src or the backend's routes,
core, hub, utils or storage is touched.

Backend: the override PUT was spelled out at 29 sites as a two-call
expression with a local import each time, and 39 tests mocked the store
by hand when a fixture does it. A `_put` helper and an `override_store`
fixture take both. -186 lines, 273 tests still pass, and the assert count
is unchanged at 624.

Frontend: eight test files become five plus a shared kit holding the
bundler-resolver registration, the localStorage fake and the chat-runtime
store fakes that three files had each written out. The resident-status
pair merge into one file, and the three identity/storage files into
another. 62 tests, 139 assertions, both unchanged.

Prose: multi-line docstrings and comment blocks in the test suites keep
their opening statement, the rest being recoverable from history. That is
most of the remaining reduction, because these tests are close to one
line per assertion already.

Two consolidations were measured and rejected rather than shipped. A
table-driven form of the source-contract tests generates 930 lines to
replace 773, since a row costs what an assert line costs. Parametrising
the backend key-folding and carry-over families saves nothing once the
helper above removes their boilerplate: what is left is the per-case
reason, not repetition.

Every mutation these tests were written to catch still reddens: reverting
new-traffic.ts, adopt-inference-status.ts, settings.py and hub-page.tsx
to their pre-fix parents each fails the expected tests.
This commit is contained in:
danielhanchen 2026-07-29 08:39:55 +00:00
commit 0c9c4f20aa
10 changed files with 985 additions and 1440 deletions

View file

@ -112,8 +112,7 @@ def _hub_error(error_type, status_code: int, message: str):
def test_the_hub_error_helper_carries_a_status_on_both_majors():
# CI runs huggingface_hub 1.x and this box 0.x, and each takes only one of the
# constructor shapes. A helper that silently dropped the response would make an
# error-mapping test pass here and fail there.
# constructor shapes.
from hub.utils.hf_errors import hf_error_status
class _Legacy(Exception):
@ -607,8 +606,7 @@ def test_a_hanging_auth_check_falls_through_to_the_download(hub, monkeypatch):
def test_a_companion_only_repo_is_not_held_at_busy(hub):
# mmproj and MTP files are companions, not quants, so such a repo is non-servable
# and falls through to the resident model. The busy probe accepted any .gguf, which
# stranded that ordinary traffic behind an unrelated multi-hour download.
# and falls through to the resident model.
assert _run("unsloth/x-GGUF:UD-Q4_K_XL").code == "model_downloading"
gb = 1024**3
hub["info"] = _Info([_Sibling("mmproj-F16.gguf", gb), _Sibling("mtp-model.gguf", gb)])
@ -1399,8 +1397,7 @@ def test_a_cold_scan_that_never_finishes_says_so_instead_of_guessing(monkeypatch
def test_a_refusal_is_never_swallowed_by_the_cannot_verify_handler(monkeypatch):
# The checks run inside a broad `except Exception` that turns a failure to decide
# into a fallthrough. An HTTPException there is a decision, but was logged as a
# failure and answered by the resident model.
# into a fallthrough.
loaded = _Loaded("unsloth/A-GGUF", "UD-Q4_K_XL")
monkeypatch.setattr(inference_route, "get_llama_cpp_backend", lambda: loaded)
monkeypatch.setattr(
@ -1466,8 +1463,7 @@ def test_a_stale_index_is_refreshed_so_a_hub_download_becomes_visible(monkeypatc
def test_an_id_v1_models_advertised_is_refused_before_the_resolver_warms(monkeypatch):
# /v1/models can advertise an unloaded local GGUF while the resolver index is cold. A bare
# id has no quant to refuse on, so without that evidence the resident model would answer.
# /v1/models can advertise an unloaded local GGUF while the resolver index is cold.
from core.inference import local_model_resolver as resolver
monkeypatch.setattr(resolver, "_scan", (0.0, {}))
@ -1522,8 +1518,7 @@ def test_an_advertised_alias_for_the_resident_weights_is_still_served(monkeypatc
def test_a_rejected_token_says_so_instead_of_asking_for_a_retry(hub):
# Hugging Face 401s an expired X-Unsloth-HF-Token. Only 403/404 were handled, so it
# fell through to a 503 telling the caller to retry something that cannot work.
# Hugging Face 401s an expired X-Unsloth-HF-Token.
from huggingface_hub.utils import HfHubHTTPError
hub["raise"] = _hub_error(HfHubHTTPError, 401, "unauthorized")
@ -1598,8 +1593,7 @@ def test_a_quant_request_is_not_satisfied_by_transformers_weights(monkeypatch):
def test_a_timed_out_download_keeps_the_slot_while_it_is_still_running(monkeypatch):
# The watch window only bounds progress reporting. Releasing on the clock while
# the worker is alive would admit a second multi-GB download beside it.
# The watch window only bounds progress reporting.
monkeypatch.setattr(auto_dl, "_MAX_WATCH_S", 0.0)
monkeypatch.setattr(auto_dl, "_WATCH_POLL_S", 0.001)
monkeypatch.setattr(auto_dl, "_TIMED_OUT_POLL_S", 0.001)
@ -1691,8 +1685,7 @@ def test_a_remote_tag_that_names_no_quant_picks_the_preferred_one(hub):
def test_a_generic_gguf_advertises_the_label_the_worker_resolves(hub):
# With no recognized quant token the extractors part ways: one takes the last
# hyphenated segment, the plan and worker key the whole stem. Dispatching ours
# made the worker exit with "No GGUF shards matching variant".
# hyphenated segment, the plan and worker key the whole stem.
from hub.utils.gguf import extract_quant_label as canonical
from hub.utils.gguf_plan import build_gguf_variant_plans
@ -1780,8 +1773,7 @@ def test_a_non_quant_tag_does_not_tear_down_a_serving_quant(monkeypatch):
def test_the_trust_probe_never_falls_back_to_the_server_identity(hub, monkeypatch):
# huggingface_hub treats None as "use the cached login", so only an explicit False
# is anonymous. This probe passed None, so a caller-named repo was read with the
# server's identity.
# is anonymous.
seen: list = []
def _probe(model_name, hf_token = None):
@ -1851,8 +1843,7 @@ def test_the_retry_after_a_failure_is_told_instead_of_restarting_it(hub, monkeyp
def test_a_completed_download_does_not_restage_the_scan_it_just_warmed(monkeypatch):
# finalize_worker_exit invalidates and warms. A second invalidation here marks
# that fresh scan stale and pushes a synchronous rescan onto the client's retry.
# finalize_worker_exit invalidates and warms.
import inspect
src = inspect.getsource(auto_dl._watch)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,131 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
import { register } from "node:module";
import type { ResidentAdoptionState } from "../../src/features/hub/lib/adopt-inference-status.ts";
import type { ResidentStatusRefreshTargets } from "../../src/features/hub/lib/resident-status-refresh.ts";
/**
* Teach the loader the two resolution rules vite and tsconfig's "bundler" mode
* give the app. Call this before the dynamic import of any src module that
* resolves the way vite and tsconfig resolve, not the way bare node does.
*/
export function registerBundlerResolver(): void {
register("../bundler-resolver.mjs", import.meta.url);
}
export type StorageFake = {
getItem: (key: string) => string | null;
setItem: (key: string, value: string) => void;
removeItem: (key: string) => void;
};
/**
* An in-memory localStorage, installed on globalThis under both the names the
* app reads it by. The returned map is the backing store, so a test can stage
* records before the module under test is imported.
*/
export function installLocalStorageFake(): {
store: Map<string, string>;
storage: StorageFake;
} {
const store = new Map<string, string>();
const storage: StorageFake = {
getItem: (key: string) => store.get(key) ?? null,
setItem: (key: string, value: string) => {
store.set(key, value);
},
removeItem: (key: string) => {
store.delete(key);
},
};
Object.assign(globalThis, {
window: { localStorage: storage },
localStorage: storage,
});
return { store, storage };
}
/** The chat-runtime store as it stands before anything has hydrated it. */
export function emptyStore(
overrides: Partial<ResidentAdoptionState> = {},
): ResidentAdoptionState {
return {
checkpoint: null,
checkpointIsExternal: false,
activeGgufVariant: null,
modelLoading: false,
...overrides,
};
}
/** Records the store actions adoptResidentModelStatus takes, in order. */
export function spies() {
const calls: string[] = [];
const previouslySeen: { checkpoint: string | null; ggufVariant: string | null }[] =
[];
return {
calls,
previouslySeen,
actions: {
setCheckpoint(checkpointId: string, ggufVariant: string | null) {
calls.push(`setCheckpoint:${checkpointId}:${ggufVariant ?? ""}`);
},
applyStatus(previous: {
checkpoint: string | null;
ggufVariant: string | null;
}) {
calls.push("applyStatus");
previouslySeen.push(previous);
},
},
};
}
/** A window/document pair whose events and visibility a test drives by hand. */
export function fakeTargets(): ResidentStatusRefreshTargets & {
hidden: boolean;
fire: (target: "window" | "document", type: string) => void;
listenerCount: () => number;
} {
const listeners = new Map<string, Set<EventListenerOrEventListenerObject>>();
const key = (target: string, type: string) => `${target}:${type}`;
const make = (target: "window" | "document") => ({
addEventListener(type: string, fn: EventListenerOrEventListenerObject) {
const set = listeners.get(key(target, type)) ?? new Set();
set.add(fn);
listeners.set(key(target, type), set);
},
removeEventListener(type: string, fn: EventListenerOrEventListenerObject) {
listeners.get(key(target, type))?.delete(fn);
},
});
const visibility = { hidden: false };
const state = {
get hidden() {
return visibility.hidden;
},
set hidden(next: boolean) {
visibility.hidden = next;
},
window: make("window"),
document: {
...make("document"),
get hidden() {
return visibility.hidden;
},
},
fire(target: "window" | "document", type: string) {
for (const fn of listeners.get(key(target, type)) ?? []) {
(fn as EventListener)(new Event(type));
}
},
listenerCount() {
let total = 0;
for (const set of listeners.values()) total += set.size;
return total;
},
};
return state as never;
}

View file

@ -1,171 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
import assert from "node:assert/strict";
import test from "node:test";
import { adoptResidentModelStatus } from "../src/features/hub/lib/adopt-inference-status.ts";
import {
ggufVariantsMatch,
residentModelIdMatches,
} from "../src/features/hub/lib/model-identity.ts";
import {
type ResidentStatusRefreshTargets,
subscribeResidentStatusRefresh,
} from "../src/features/hub/lib/resident-status-refresh.ts";
function fakeTargets(): ResidentStatusRefreshTargets & {
hidden: boolean;
fire: (target: "window" | "document", type: string) => void;
listenerCount: () => number;
} {
const listeners = new Map<string, Set<EventListenerOrEventListenerObject>>();
const key = (target: string, type: string) => `${target}:${type}`;
const make = (target: "window" | "document") => ({
addEventListener(type: string, fn: EventListenerOrEventListenerObject) {
const set = listeners.get(key(target, type)) ?? new Set();
set.add(fn);
listeners.set(key(target, type), set);
},
removeEventListener(type: string, fn: EventListenerOrEventListenerObject) {
listeners.get(key(target, type))?.delete(fn);
},
});
const visibility = { hidden: false };
const state = {
get hidden() {
return visibility.hidden;
},
set hidden(next: boolean) {
visibility.hidden = next;
},
window: make("window"),
document: {
...make("document"),
get hidden() {
return visibility.hidden;
},
},
fire(target: "window" | "document", type: string) {
for (const fn of listeners.get(key(target, type)) ?? []) {
(fn as EventListener)(new Event(type));
}
},
listenerCount() {
let total = 0;
for (const set of listeners.values()) total += set.size;
return total;
},
};
return state as never;
}
test("coming back to the window re-reads inference status", () => {
// An OpenAI-compatible request auto-switches the resident model whenever it
// likes. The Hub's only other status read is its mount effect, so without this
// the catalog and the settings page keep describing the previous model for as
// long as the Hub stays mounted.
const targets = fakeTargets();
let reads = 0;
subscribeResidentStatusRefresh(() => {
reads += 1;
}, targets);
assert.equal(reads, 0, "subscribing must not read on its own");
targets.fire("window", "focus");
assert.equal(reads, 1);
targets.fire("document", "visibilitychange");
assert.equal(reads, 2);
});
test("a tab going hidden does not read", () => {
// visibilitychange fires on the way out too, and a hidden tab has no settings
// page to correct.
const targets = fakeTargets();
let reads = 0;
subscribeResidentStatusRefresh(() => {
reads += 1;
}, targets);
targets.hidden = true;
targets.fire("document", "visibilitychange");
assert.equal(reads, 0);
targets.hidden = false;
targets.fire("document", "visibilitychange");
assert.equal(reads, 1);
});
test("an auto-switch under a mounted Hub stops hiding the live config", () => {
// The whole point, end to end: while the Hub is mounted an OpenAI-compatible
// request swaps the resident model. Without a second read the store still names
// the old one, so hub-page's settingsTargetIsResident says the newly loaded
// model is not resident, its settings page is handed loadedConfig=null, and
// ModelConfigPage seeds the editor from saved/default values -- which Apply then
// reloads the model with, over what the API actually selected.
const store = {
checkpoint: "unsloth/Qwen3-8B-GGUF" as string | null,
checkpointIsExternal: false,
activeGgufVariant: "Q4_K_M" as string | null,
modelLoading: false,
};
// What the server reports once the API request has switched it.
let serverStatus = {
checkpointId: "unsloth/Llama-3.1-8B-Instruct-GGUF",
ggufVariant: "Q8_0",
};
const readStatusAndAdopt = () => {
adoptResidentModelStatus(
serverStatus,
{ ...store },
{
setCheckpoint: (checkpointId, ggufVariant) => {
store.checkpoint = checkpointId;
store.activeGgufVariant = ggufVariant;
},
applyStatus: () => undefined,
},
);
};
// hub-page.tsx's settingsTargetIsResident, for the model the API just loaded.
const settingsTargetIsResident = () =>
residentModelIdMatches(store.checkpoint, serverStatus.checkpointId) &&
ggufVariantsMatch(store.activeGgufVariant, serverStatus.ggufVariant);
const targets = fakeTargets();
subscribeResidentStatusRefresh(readStatusAndAdopt, targets);
assert.equal(
settingsTargetIsResident(),
false,
"precondition: the mount-time read predates the switch",
);
targets.fire("window", "focus");
assert.equal(settingsTargetIsResident(), true);
// A load this tab started owns the store until it settles, so a refresh landing
// mid-switch must not re-pin the model the user is moving away from.
store.modelLoading = true;
serverStatus = {
checkpointId: "unsloth/Qwen3-8B-GGUF",
ggufVariant: "Q4_K_M",
};
targets.fire("window", "focus");
assert.equal(store.checkpoint, "unsloth/Llama-3.1-8B-Instruct-GGUF");
});
test("unsubscribing stops the reads and leaves no listener behind", () => {
const targets = fakeTargets();
let reads = 0;
const unsubscribe = subscribeResidentStatusRefresh(() => {
reads += 1;
}, targets);
assert.equal(targets.listenerCount(), 2);
unsubscribe();
assert.equal(targets.listenerCount(), 0);
targets.fire("window", "focus");
targets.fire("document", "visibilitychange");
assert.equal(reads, 0);
});

View file

@ -4,47 +4,37 @@
import assert from "node:assert/strict";
import test from "node:test";
import { adoptResidentModelStatus } from "../src/features/hub/lib/adopt-inference-status.ts";
import {
type ResidentAdoptionState,
adoptResidentModelStatus,
} from "../src/features/hub/lib/adopt-inference-status.ts";
ggufVariantsMatch,
residentModelIdMatches,
} from "../src/features/hub/lib/model-identity.ts";
import { subscribeResidentStatusRefresh } from "../src/features/hub/lib/resident-status-refresh.ts";
import { emptyStore, fakeTargets, spies } from "./helpers/kit.ts";
const RESIDENT = {
checkpointId: "unsloth/Qwen3-8B-GGUF",
ggufVariant: "Q4_K_M",
};
function emptyStore(
overrides: Partial<ResidentAdoptionState> = {},
): ResidentAdoptionState {
return {
checkpoint: null,
checkpointIsExternal: false,
activeGgufVariant: null,
modelLoading: false,
...overrides,
/**
* Store actions that refuse to be called. The message on each names what must
* not happen, so a test states its rule by the action it declines to forbid.
*/
function refusing(messages: {
setCheckpoint?: string;
clearCheckpoint?: string;
applyStatus?: string;
}) {
const refuse = (message = "unreachable") => {
return () => {
throw new Error(message);
};
};
}
function spies() {
const calls: string[] = [];
const previouslySeen: { checkpoint: string | null; ggufVariant: string | null }[] =
[];
return {
calls,
previouslySeen,
actions: {
setCheckpoint(checkpointId: string, ggufVariant: string | null) {
calls.push(`setCheckpoint:${checkpointId}:${ggufVariant ?? ""}`);
},
applyStatus(previous: {
checkpoint: string | null;
ggufVariant: string | null;
}) {
calls.push("applyStatus");
previouslySeen.push(previous);
},
},
setCheckpoint: refuse(messages.setCheckpoint),
clearCheckpoint: refuse(messages.clearCheckpoint),
applyStatus: refuse(messages.applyStatus),
};
}
@ -157,22 +147,18 @@ test("an empty status drops a local checkpoint the server no longer has", () =>
const cleared: string[] = [];
const adopted = adoptResidentModelStatus(
{ checkpointId: null, ggufVariant: null },
{
emptyStore({
checkpoint: "/models/llama.gguf",
checkpointIsExternal: false,
activeGgufVariant: "Q4_K_M",
modelLoading: false,
},
}),
{
setCheckpoint: () => {
throw new Error("nothing is resident, so nothing may be pinned");
},
...refusing({
setCheckpoint: "nothing is resident, so nothing may be pinned",
applyStatus: "there is no status to apply",
}),
clearCheckpoint: () => {
cleared.push("cleared");
},
applyStatus: () => {
throw new Error("there is no status to apply");
},
},
);
assert.equal(adopted, true);
@ -184,23 +170,13 @@ test("an empty status leaves an external pick alone", () => {
// status must not reach it: the local model is not what the user is talking to.
const adopted = adoptResidentModelStatus(
{ checkpointId: null, ggufVariant: null },
{
emptyStore({
checkpoint: "gemini/gemini-2.5-pro",
checkpointIsExternal: true,
activeGgufVariant: null,
modelLoading: false,
},
{
setCheckpoint: () => {
throw new Error("unreachable");
},
clearCheckpoint: () => {
throw new Error("an external pick must survive an empty status");
},
applyStatus: () => {
throw new Error("unreachable");
},
},
}),
refusing({
clearCheckpoint: "an external pick must survive an empty status",
}),
);
assert.equal(adopted, false);
});
@ -208,23 +184,11 @@ test("an empty status leaves an external pick alone", () => {
test("an empty status does not fight a load this tab started", () => {
const adopted = adoptResidentModelStatus(
{ checkpointId: null, ggufVariant: null },
{
emptyStore({
checkpoint: "/models/llama.gguf",
checkpointIsExternal: false,
activeGgufVariant: null,
modelLoading: true,
},
{
setCheckpoint: () => {
throw new Error("unreachable");
},
clearCheckpoint: () => {
throw new Error("the load owns the store until it settles");
},
applyStatus: () => {
throw new Error("unreachable");
},
},
}),
refusing({ clearCheckpoint: "the load owns the store until it settles" }),
);
assert.equal(adopted, false);
});
@ -232,23 +196,116 @@ test("an empty status does not fight a load this tab started", () => {
test("an empty status on an already empty store changes nothing", () => {
const adopted = adoptResidentModelStatus(
{ checkpointId: null, ggufVariant: null },
{
checkpoint: null,
checkpointIsExternal: false,
activeGgufVariant: null,
modelLoading: false,
},
{
setCheckpoint: () => {
throw new Error("unreachable");
},
clearCheckpoint: () => {
throw new Error("there is nothing to clear");
},
applyStatus: () => {
throw new Error("unreachable");
},
},
emptyStore(),
refusing({ clearCheckpoint: "there is nothing to clear" }),
);
assert.equal(adopted, false);
});
test("coming back to the window re-reads inference status", () => {
// An OpenAI-compatible request auto-switches the resident model whenever it
// likes. The Hub's only other status read is its mount effect, so without this
// the catalog and the settings page keep describing the previous model for as
// long as the Hub stays mounted.
const targets = fakeTargets();
let reads = 0;
subscribeResidentStatusRefresh(() => {
reads += 1;
}, targets);
assert.equal(reads, 0, "subscribing must not read on its own");
targets.fire("window", "focus");
assert.equal(reads, 1);
targets.fire("document", "visibilitychange");
assert.equal(reads, 2);
});
test("a tab going hidden does not read", () => {
// visibilitychange fires on the way out too, and a hidden tab has no settings
// page to correct.
const targets = fakeTargets();
let reads = 0;
subscribeResidentStatusRefresh(() => {
reads += 1;
}, targets);
targets.hidden = true;
targets.fire("document", "visibilitychange");
assert.equal(reads, 0);
targets.hidden = false;
targets.fire("document", "visibilitychange");
assert.equal(reads, 1);
});
test("an auto-switch under a mounted Hub stops hiding the live config", () => {
// The whole point, end to end: while the Hub is mounted an OpenAI-compatible
// request swaps the resident model. Without a second read the store still names
// the old one, so hub-page's settingsTargetIsResident says the newly loaded
// model is not resident, its settings page is handed loadedConfig=null, and
// ModelConfigPage seeds the editor from saved/default values -- which Apply then
// reloads the model with, over what the API actually selected.
const store = emptyStore({
checkpoint: "unsloth/Qwen3-8B-GGUF",
activeGgufVariant: "Q4_K_M",
});
// What the server reports once the API request has switched it.
let serverStatus = {
checkpointId: "unsloth/Llama-3.1-8B-Instruct-GGUF",
ggufVariant: "Q8_0",
};
const readStatusAndAdopt = () => {
adoptResidentModelStatus(
serverStatus,
{ ...store },
{
setCheckpoint: (checkpointId, ggufVariant) => {
store.checkpoint = checkpointId;
store.activeGgufVariant = ggufVariant;
},
applyStatus: () => undefined,
},
);
};
// hub-page.tsx's settingsTargetIsResident, for the model the API just loaded.
const settingsTargetIsResident = () =>
residentModelIdMatches(store.checkpoint, serverStatus.checkpointId) &&
ggufVariantsMatch(store.activeGgufVariant, serverStatus.ggufVariant);
const targets = fakeTargets();
subscribeResidentStatusRefresh(readStatusAndAdopt, targets);
assert.equal(
settingsTargetIsResident(),
false,
"precondition: the mount-time read predates the switch",
);
targets.fire("window", "focus");
assert.equal(settingsTargetIsResident(), true);
// A load this tab started owns the store until it settles, so a refresh landing
// mid-switch must not re-pin the model the user is moving away from.
store.modelLoading = true;
serverStatus = {
checkpointId: "unsloth/Qwen3-8B-GGUF",
ggufVariant: "Q4_K_M",
};
targets.fire("window", "focus");
assert.equal(store.checkpoint, "unsloth/Llama-3.1-8B-Instruct-GGUF");
});
test("unsubscribing stops the reads and leaves no listener behind", () => {
const targets = fakeTargets();
let reads = 0;
const unsubscribe = subscribeResidentStatusRefresh(() => {
reads += 1;
}, targets);
assert.equal(targets.listenerCount(), 2);
unsubscribe();
assert.equal(targets.listenerCount(), 0);
targets.fire("window", "focus");
targets.fire("document", "visibilitychange");
assert.equal(reads, 0);
});

View file

@ -0,0 +1,344 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
import assert from "node:assert/strict";
import test from "node:test";
import { settingsGgufVariantForRow } from "../src/features/hub/inventory/settings-identity.ts";
import type {
CachedInventoryRow,
LocalInventoryRow,
} from "../src/features/hub/inventory/types.ts";
import {
isOllamaLinkPath,
modelIdsMatch,
publicModelId,
residentModelIdMatches,
} from "../src/features/hub/lib/model-identity.ts";
import {
installLocalStorageFake,
registerBundlerResolver,
} from "./helpers/kit.ts";
registerBundlerResolver();
const { store, storage } = installLocalStorageFake();
const REPO_KEY = 'v2:["unsloth/repo-gguf","q4_k_m"]';
// The legacy import of unsloth_load_settings runs once, on the first read after
// load, so it has to be staged before the module is imported.
store.set(
"unsloth_model_configs",
JSON.stringify({ [REPO_KEY]: { version: 1, maxSeqLength: 32768 } }),
);
store.set(
"unsloth_load_settings",
JSON.stringify({ "Unsloth/Repo-GGUF::Q4_K_M": { contextLength: 8192 } }),
);
const { listPerModelConfigs, resolveInitialConfig, savePerModelConfig } =
await import("../src/features/model-picker/model-config/per-model-config.ts");
const { modelStorageKey, splitQuantSuffix } = await import(
"../src/features/model-picker/model-config/model-identity.ts"
);
function config(maxSeqLength: number, kvCacheDtype: string | null = null) {
return {
customContextLength: null,
maxSeqLength,
kvCacheDtype,
speculativeType: null,
specDraftNMax: null,
nParallel: null,
tensorParallel: false,
chatTemplateOverride: null,
};
}
function storedKeys(): string[] {
return Object.keys(
JSON.parse(storage.getItem("unsloth_model_configs") ?? "{}"),
);
}
test("publicModelId mirrors what /status reports for a path-loaded model", () => {
// Mirrors public_model_id in studio/backend/core/inference/model_ids.py.
assert.equal(
publicModelId("/srv/models/Qwen3-8B-Q4_K_M.gguf"),
"Qwen3-8B-Q4_K_M",
);
assert.equal(
publicModelId(
"/home/u/.cache/huggingface/hub/models--unsloth--Qwen3-8B-GGUF/snapshots/abc123",
),
"unsloth/Qwen3-8B-GGUF",
);
assert.equal(publicModelId("C:\\models\\Foo-Q4_K_M.gguf"), "Foo-Q4_K_M");
assert.equal(publicModelId("~/models/Foo.gguf"), "Foo");
assert.equal(publicModelId("/srv/models/repo/"), "repo");
// A repo id and an already-clean name come back untouched.
assert.equal(publicModelId("unsloth/Qwen3-8B-GGUF"), "unsloth/Qwen3-8B-GGUF");
assert.equal(publicModelId("Qwen3-8B-Q4_K_M"), "Qwen3-8B-Q4_K_M");
// "models--" alone is not the cache layout; only the snapshots sibling is.
assert.equal(publicModelId("models--only--nosnapshots/blobs/x"), "x");
});
test("a resident path-loaded model is matched by the id /status reports", () => {
// A loose .gguf: the catalog row is keyed by the path, and the Hub page records
// the loadable identifier (status.model_identifier), so the literal pass answers.
assert.equal(
modelIdsMatch("Qwen3-8B-Q4_K_M", "/srv/models/Qwen3-8B-Q4_K_M.gguf"),
false,
);
assert.equal(
residentModelIdMatches(
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
),
true,
);
// A repo in an inactive HF cache loads by snapshot path but keeps the repo id
// as its settings identity, so the configId alias already covers it.
assert.equal(
residentModelIdMatches(
"unsloth/Qwen3-8B-GGUF",
"/mnt/old-cache/models--unsloth--Qwen3-8B-GGUF/snapshots/abc123",
"unsloth/Qwen3-8B-GGUF",
),
true,
);
// The raw identifier is still matched literally.
assert.equal(
residentModelIdMatches(
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
null,
),
true,
);
// Another model is still not the loaded one.
assert.equal(
residentModelIdMatches(
"Qwen3-8B-Q4_K_M",
"/srv/models/Llama-3-8B-Q4_K_M.gguf",
null,
),
false,
);
assert.equal(
residentModelIdMatches(
"unsloth/Qwen3-8B-GGUF",
"/mnt/old-cache/models--unsloth--Llama-3-GGUF/snapshots/abc123",
"unsloth/Llama-3-GGUF",
),
false,
);
assert.equal(residentModelIdMatches(null, "/srv/models/x.gguf"), false);
assert.equal(residentModelIdMatches("Qwen3-8B-Q4_K_M"), false);
});
test("a shared filename or folder name never marks a row resident", () => {
// Two loose GGUFs with the same filename in different folders collapse onto one
// public id, so a stem can only say "one of these", never which.
const loaded = "/srv/models/alpha/model.gguf";
const other = "/srv/models/beta/model.gguf";
assert.equal(publicModelId(loaded), publicModelId(other));
assert.equal(residentModelIdMatches(publicModelId(loaded), other, other), false);
// The loadable identifier names exactly one of them.
assert.equal(residentModelIdMatches(loaded, loaded, loaded), true);
assert.equal(residentModelIdMatches(loaded, other, other), false);
// Same collapse one level up: two model directories sharing a basename.
const loadedDir = "/srv/lmstudio/publisher-a/Llama-3-8B-GGUF";
const otherDir = "/srv/models/publisher-b/Llama-3-8B-GGUF";
assert.equal(publicModelId(loadedDir), publicModelId(otherDir));
assert.equal(
residentModelIdMatches(publicModelId(loadedDir), otherDir, otherDir),
false,
);
// A cache snapshot still collapses onto its repo id, which names one model.
assert.equal(
residentModelIdMatches(
"unsloth/Qwen3-8B-GGUF",
"/mnt/old-cache/models--unsloth--Qwen3-8B-GGUF/snapshots/abc123",
null,
),
true,
);
});
test("Ollama link paths are recognised the way the resolver excludes them", () => {
// core/inference/local_model_resolver.py refuses any path with these segments.
assert.equal(
isOllamaLinkPath("/home/u/.ollama/models/.studio_links/q/qwen3-Q4_K_M.gguf"),
true,
);
assert.equal(
isOllamaLinkPath("/home/u/.cache/unsloth/ollama_links/ab12/llama3.gguf"),
true,
);
assert.equal(
isOllamaLinkPath("C:\\Users\\u\\.ollama\\models\\.studio_links\\q\\a.gguf"),
true,
);
// Only those exact segments, not a directory that merely contains the name.
assert.equal(isOllamaLinkPath("/srv/studio_links_backup/a.gguf"), false);
assert.equal(isOllamaLinkPath("/srv/models/Qwen3-8B-Q4_K_M.gguf"), false);
assert.equal(isOllamaLinkPath("unsloth/Qwen3-8B-GGUF"), false);
assert.equal(isOllamaLinkPath(null), false);
});
test("a standalone gguf keeps one settings identity across surfaces", () => {
const loose = {
kind: "local",
path: "/srv/models/Qwen3-8B-Q4_K_M.gguf",
// What hub/services/models/common.py emits for a single scanned file.
formatVariant: "Q4_K_M",
} as LocalInventoryRow;
// The Chat picker opens the same file with no variant, so the Hub row must not
// adopt the filename-derived label or the two edit different configs.
assert.equal(settingsGgufVariantForRow(loose), null);
// A GGUF directory still has a variant slot for the quant lookup to fill.
const repoDir = {
kind: "local",
path: "/srv/models/Qwen3-8B-GGUF",
formatVariant: null,
} as LocalInventoryRow;
assert.equal(settingsGgufVariantForRow(repoDir), null);
const lmStudioDir = {
kind: "local",
path: "/srv/lmstudio/Qwen3-8B-GGUF",
formatVariant: "Q8_0",
} as LocalInventoryRow;
assert.equal(settingsGgufVariantForRow(lmStudioDir), "Q8_0");
// Cached repo rows are unaffected (cache_inventory.py never sets one).
const cached = { kind: "cache", formatVariant: null } as CachedInventoryRow;
assert.equal(settingsGgufVariantForRow(cached), null);
});
// The one-time backfill re-reads listPerModelConfigs() to pick up a save that
// landed while the override fetch was in flight, and matches on the folded
// identity. That is only unambiguous because storage holds one record per model,
// so these pin that rule rather than the backfill.
test("importing the legacy load settings never doubles up a model", () => {
// The typed casing in unsloth_load_settings names the model the v2 record
// already holds, so the import has to leave it alone rather than add a second
// record the picker would prefer and the backfill would not.
assert.deepEqual(listPerModelConfigs().length, 1);
assert.deepEqual(storedKeys(), [REPO_KEY]);
assert.equal(
resolveInitialConfig("unsloth/repo-gguf", "q4_k_m").config
.customContextLength,
null,
);
});
test("two spellings of one model id keep a single stored record", () => {
store.clear();
savePerModelConfig("Unsloth/Repo-GGUF", "Q4_K_M", config(4096));
savePerModelConfig("unsloth/repo-gguf", "q4_k_m", config(32768, "q8_0"));
assert.deepEqual(storedKeys(), [REPO_KEY]);
const listed = listPerModelConfigs();
assert.equal(listed.length, 1);
assert.equal(listed[0]?.config.maxSeqLength, 32768);
// What the picker applies and the only thing the backfill can see agree.
assert.equal(
resolveInitialConfig("Unsloth/Repo-GGUF", "Q4_K_M").config.maxSeqLength,
32768,
);
});
test("two spellings of one Windows path keep a single stored record", () => {
store.clear();
savePerModelConfig("C:\\Models\\Foo.gguf", null, config(4096));
savePerModelConfig("c:/models/foo.gguf", null, config(32768, "q8_0"));
assert.deepEqual(storedKeys(), ['v2:["c:/models/foo.gguf",""]']);
assert.equal(listPerModelConfigs().length, 1);
});
test("a POSIX path is case sensitive, so its two spellings stay separate", () => {
store.clear();
savePerModelConfig("/models/Foo.gguf", null, config(4096));
savePerModelConfig("/models/foo.gguf", null, config(32768, "q8_0"));
assert.equal(storedKeys().length, 2);
assert.equal(
resolveInitialConfig("/models/Foo.gguf", null).config.maxSeqLength,
4096,
);
});
// Every answer below is the one split_quant_suffix in
// studio/backend/utils/openai_auto_switch_settings.py gives for the same key. The
// backfill folds a stored key with this before comparing it against the server's,
// so a suffix this splits and the backend does not collapses two models onto one
// key on the browser side only.
const CASES: [string, [string, string] | null][] = [
// A known quant label, with and without the optional bpw modifier.
["org/Repo-GGUF:Q4_K_M", ["org/Repo-GGUF", "Q4_K_M"]],
["org/Repo-GGUF:IQ4_XS-3.53bpw", ["org/Repo-GGUF", "IQ4_XS-3.53bpw"]],
["org/Repo-GGUF:UD-Q4_K_XL", ["org/Repo-GGUF", "UD-Q4_K_XL"]],
// A .gguf with no quant token in its name is labelled by its stem, and storage
// lowercases the label while the scanner keeps the filename's casing.
["/models/CustomModel.gguf:custommodel", ["/models/CustomModel.gguf", "custommodel"]],
["/models/CustomModel.gguf:CustomModel", ["/models/CustomModel.gguf", "CustomModel"]],
["C:\\models\\CustomModel.gguf:custommodel", ["C:\\models\\CustomModel.gguf", "custommodel"]],
// A shard suffix is not part of the label.
[
"/models/Custom-00001-of-00003.gguf:custom",
["/models/Custom-00001-of-00003.gguf", "custom"],
],
["/models/Custom-00001-of-00003.gguf:custom-00001-of-00003", null],
// An extensionless .gguf still has a label.
["/models/.gguf:gguf", ["/models/.gguf", "gguf"]],
// A quant token inside the filename wins over the stem.
["/models/tinyllama-Q4_K_M.gguf:q4_k_m", ["/models/tinyllama-Q4_K_M.gguf", "q4_k_m"]],
["/models/tinyllama-Q4_K_M.gguf:tinyllama-q4_k_m", null],
// Only the basename is labelled, never the directories above it.
[
"/models/dir/CustomModel.gguf:custommodel",
["/models/dir/CustomModel.gguf", "custommodel"],
],
["/models/dir/CustomModel.gguf:dir/custommodel", null],
// A colon is legal in a POSIX filename. Neither of these is a variant, and
// reading them as one folds two real files onto a single key.
["/models/foo:Bar.gguf", null],
["/models/foo:bar.gguf", null],
["/models/llama.gguf:Bar.gguf", null],
["/models/llama.gguf:bar.gguf", null],
["/models/CustomModel.gguf:othermodel", null],
["/models/model.gguf:notalabel", null],
["/models/plain.gguf:plain:extra", null],
// A Windows drive letter is not a separator either.
["C:\\models\\foo.gguf", null],
["C:/models/foo.gguf", null],
// Nothing to split.
["org/Repo-GGUF", null],
["/models/foo.gguf", null],
["org/Repo:", null],
[":Q4_K_M", null],
];
test("splitQuantSuffix answers exactly as the backend's split_quant_suffix", () => {
for (const [value, expected] of CASES) {
assert.deepEqual(splitQuantSuffix(value), expected, value);
}
});
test("a .gguf filename carrying a colon is not folded into a variant", () => {
// Two real, distinct files: POSIX allows a colon in a name and is case
// sensitive, so the one-time backfill has to keep their settings apart. The
// variant half of an override key is stored lowercased, so folding these makes
// one key and strands whichever file the backfill reaches second.
const upper = "/models/llama.gguf:Bar.gguf";
const lower = "/models/llama.gguf:bar.gguf";
assert.equal(splitQuantSuffix(upper), null);
assert.equal(splitQuantSuffix(lower), null);
assert.notEqual(modelStorageKey(upper, null), modelStorageKey(lower, null));
});

View file

@ -1,176 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
import assert from "node:assert/strict";
import test from "node:test";
import { settingsGgufVariantForRow } from "../src/features/hub/inventory/settings-identity.ts";
import type {
CachedInventoryRow,
LocalInventoryRow,
} from "../src/features/hub/inventory/types.ts";
import {
isOllamaLinkPath,
modelIdsMatch,
publicModelId,
residentModelIdMatches,
} from "../src/features/hub/lib/model-identity.ts";
test("publicModelId mirrors what /status reports for a path-loaded model", () => {
// Mirrors public_model_id in studio/backend/core/inference/model_ids.py.
assert.equal(
publicModelId("/srv/models/Qwen3-8B-Q4_K_M.gguf"),
"Qwen3-8B-Q4_K_M",
);
assert.equal(
publicModelId(
"/home/u/.cache/huggingface/hub/models--unsloth--Qwen3-8B-GGUF/snapshots/abc123",
),
"unsloth/Qwen3-8B-GGUF",
);
assert.equal(publicModelId("C:\\models\\Foo-Q4_K_M.gguf"), "Foo-Q4_K_M");
assert.equal(publicModelId("~/models/Foo.gguf"), "Foo");
assert.equal(publicModelId("/srv/models/repo/"), "repo");
// A repo id and an already-clean name come back untouched.
assert.equal(publicModelId("unsloth/Qwen3-8B-GGUF"), "unsloth/Qwen3-8B-GGUF");
assert.equal(publicModelId("Qwen3-8B-Q4_K_M"), "Qwen3-8B-Q4_K_M");
// "models--" alone is not the cache layout; only the snapshots sibling is.
assert.equal(publicModelId("models--only--nosnapshots/blobs/x"), "x");
});
test("a resident path-loaded model is matched by the id /status reports", () => {
// A loose .gguf: the catalog row is keyed by the path, and the Hub page records
// the loadable identifier (status.model_identifier), so the literal pass answers.
assert.equal(
modelIdsMatch("Qwen3-8B-Q4_K_M", "/srv/models/Qwen3-8B-Q4_K_M.gguf"),
false,
);
assert.equal(
residentModelIdMatches(
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
),
true,
);
// A repo in an inactive HF cache loads by snapshot path but keeps the repo id
// as its settings identity, so the configId alias already covers it.
assert.equal(
residentModelIdMatches(
"unsloth/Qwen3-8B-GGUF",
"/mnt/old-cache/models--unsloth--Qwen3-8B-GGUF/snapshots/abc123",
"unsloth/Qwen3-8B-GGUF",
),
true,
);
// The raw identifier is still matched literally.
assert.equal(
residentModelIdMatches(
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
"/srv/models/Qwen3-8B-Q4_K_M.gguf",
null,
),
true,
);
// Another model is still not the loaded one.
assert.equal(
residentModelIdMatches(
"Qwen3-8B-Q4_K_M",
"/srv/models/Llama-3-8B-Q4_K_M.gguf",
null,
),
false,
);
assert.equal(
residentModelIdMatches(
"unsloth/Qwen3-8B-GGUF",
"/mnt/old-cache/models--unsloth--Llama-3-GGUF/snapshots/abc123",
"unsloth/Llama-3-GGUF",
),
false,
);
assert.equal(residentModelIdMatches(null, "/srv/models/x.gguf"), false);
assert.equal(residentModelIdMatches("Qwen3-8B-Q4_K_M"), false);
});
test("a shared filename or folder name never marks a row resident", () => {
// Two loose GGUFs with the same filename in different folders collapse onto one
// public id, so a stem can only say "one of these", never which.
const loaded = "/srv/models/alpha/model.gguf";
const other = "/srv/models/beta/model.gguf";
assert.equal(publicModelId(loaded), publicModelId(other));
assert.equal(residentModelIdMatches(publicModelId(loaded), other, other), false);
// The loadable identifier names exactly one of them.
assert.equal(residentModelIdMatches(loaded, loaded, loaded), true);
assert.equal(residentModelIdMatches(loaded, other, other), false);
// Same collapse one level up: two model directories sharing a basename.
const loadedDir = "/srv/lmstudio/publisher-a/Llama-3-8B-GGUF";
const otherDir = "/srv/models/publisher-b/Llama-3-8B-GGUF";
assert.equal(publicModelId(loadedDir), publicModelId(otherDir));
assert.equal(
residentModelIdMatches(publicModelId(loadedDir), otherDir, otherDir),
false,
);
// A cache snapshot still collapses onto its repo id, which names one model.
assert.equal(
residentModelIdMatches(
"unsloth/Qwen3-8B-GGUF",
"/mnt/old-cache/models--unsloth--Qwen3-8B-GGUF/snapshots/abc123",
null,
),
true,
);
});
test("Ollama link paths are recognised the way the resolver excludes them", () => {
// core/inference/local_model_resolver.py refuses any path with these segments.
assert.equal(
isOllamaLinkPath("/home/u/.ollama/models/.studio_links/q/qwen3-Q4_K_M.gguf"),
true,
);
assert.equal(
isOllamaLinkPath("/home/u/.cache/unsloth/ollama_links/ab12/llama3.gguf"),
true,
);
assert.equal(
isOllamaLinkPath("C:\\Users\\u\\.ollama\\models\\.studio_links\\q\\a.gguf"),
true,
);
// Only those exact segments, not a directory that merely contains the name.
assert.equal(isOllamaLinkPath("/srv/studio_links_backup/a.gguf"), false);
assert.equal(isOllamaLinkPath("/srv/models/Qwen3-8B-Q4_K_M.gguf"), false);
assert.equal(isOllamaLinkPath("unsloth/Qwen3-8B-GGUF"), false);
assert.equal(isOllamaLinkPath(null), false);
});
test("a standalone gguf keeps one settings identity across surfaces", () => {
const loose = {
kind: "local",
path: "/srv/models/Qwen3-8B-Q4_K_M.gguf",
// What hub/services/models/common.py emits for a single scanned file.
formatVariant: "Q4_K_M",
} as LocalInventoryRow;
// The Chat picker opens the same file with no variant, so the Hub row must not
// adopt the filename-derived label or the two edit different configs.
assert.equal(settingsGgufVariantForRow(loose), null);
// A GGUF directory still has a variant slot for the quant lookup to fill.
const repoDir = {
kind: "local",
path: "/srv/models/Qwen3-8B-GGUF",
formatVariant: null,
} as LocalInventoryRow;
assert.equal(settingsGgufVariantForRow(repoDir), null);
const lmStudioDir = {
kind: "local",
path: "/srv/lmstudio/Qwen3-8B-GGUF",
formatVariant: "Q8_0",
} as LocalInventoryRow;
assert.equal(settingsGgufVariantForRow(lmStudioDir), "Q8_0");
// Cached repo rows are unaffected (cache_inventory.py never sets one).
const cached = { kind: "cache", formatVariant: null } as CachedInventoryRow;
assert.equal(settingsGgufVariantForRow(cached), null);
});

View file

@ -1,112 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
import assert from "node:assert/strict";
import { register } from "node:module";
import test from "node:test";
register("./bundler-resolver.mjs", import.meta.url);
const store = new Map<string, string>();
const storage = {
getItem: (key: string) => store.get(key) ?? null,
setItem: (key: string, value: string) => {
store.set(key, value);
},
removeItem: (key: string) => {
store.delete(key);
},
};
Object.assign(globalThis, {
window: { localStorage: storage },
localStorage: storage,
});
const REPO_KEY = 'v2:["unsloth/repo-gguf","q4_k_m"]';
// The legacy import of unsloth_load_settings runs once, on the first read after
// load, so it has to be staged before the module is imported.
store.set(
"unsloth_model_configs",
JSON.stringify({ [REPO_KEY]: { version: 1, maxSeqLength: 32768 } }),
);
store.set(
"unsloth_load_settings",
JSON.stringify({ "Unsloth/Repo-GGUF::Q4_K_M": { contextLength: 8192 } }),
);
const { listPerModelConfigs, resolveInitialConfig, savePerModelConfig } =
await import("../src/features/model-picker/model-config/per-model-config.ts");
function config(maxSeqLength: number, kvCacheDtype: string | null = null) {
return {
customContextLength: null,
maxSeqLength,
kvCacheDtype,
speculativeType: null,
specDraftNMax: null,
nParallel: null,
tensorParallel: false,
chatTemplateOverride: null,
};
}
function storedKeys(): string[] {
return Object.keys(
JSON.parse(storage.getItem("unsloth_model_configs") ?? "{}"),
);
}
// The one-time backfill re-reads listPerModelConfigs() to pick up a save that
// landed while the override fetch was in flight, and matches on the folded
// identity. That is only unambiguous because storage holds one record per model,
// so these pin that rule rather than the backfill.
test("importing the legacy load settings never doubles up a model", () => {
// The typed casing in unsloth_load_settings names the model the v2 record
// already holds, so the import has to leave it alone rather than add a second
// record the picker would prefer and the backfill would not.
assert.deepEqual(listPerModelConfigs().length, 1);
assert.deepEqual(storedKeys(), [REPO_KEY]);
assert.equal(
resolveInitialConfig("unsloth/repo-gguf", "q4_k_m").config
.customContextLength,
null,
);
});
test("two spellings of one model id keep a single stored record", () => {
store.clear();
savePerModelConfig("Unsloth/Repo-GGUF", "Q4_K_M", config(4096));
savePerModelConfig("unsloth/repo-gguf", "q4_k_m", config(32768, "q8_0"));
assert.deepEqual(storedKeys(), [REPO_KEY]);
const listed = listPerModelConfigs();
assert.equal(listed.length, 1);
assert.equal(listed[0]?.config.maxSeqLength, 32768);
// What the picker applies and the only thing the backfill can see agree.
assert.equal(
resolveInitialConfig("Unsloth/Repo-GGUF", "Q4_K_M").config.maxSeqLength,
32768,
);
});
test("two spellings of one Windows path keep a single stored record", () => {
store.clear();
savePerModelConfig("C:\\Models\\Foo.gguf", null, config(4096));
savePerModelConfig("c:/models/foo.gguf", null, config(32768, "q8_0"));
assert.deepEqual(storedKeys(), ['v2:["c:/models/foo.gguf",""]']);
assert.equal(listPerModelConfigs().length, 1);
});
test("a POSIX path is case sensitive, so its two spellings stay separate", () => {
store.clear();
savePerModelConfig("/models/Foo.gguf", null, config(4096));
savePerModelConfig("/models/foo.gguf", null, config(32768, "q8_0"));
assert.equal(storedKeys().length, 2);
assert.equal(
resolveInitialConfig("/models/Foo.gguf", null).config.maxSeqLength,
4096,
);
});

View file

@ -1,83 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
import assert from "node:assert/strict";
import { register } from "node:module";
import test from "node:test";
// The module under test resolves the way vite and tsconfig resolve, not the way
// bare node does.
register("./bundler-resolver.mjs", import.meta.url);
const { modelStorageKey, splitQuantSuffix } = await import(
"../src/features/model-picker/model-config/model-identity.ts"
);
// Every answer below is the one split_quant_suffix in
// studio/backend/utils/openai_auto_switch_settings.py gives for the same key. The
// backfill folds a stored key with this before comparing it against the server's,
// so a suffix this splits and the backend does not collapses two models onto one
// key on the browser side only.
const CASES: [string, [string, string] | null][] = [
// A known quant label, with and without the optional bpw modifier.
["org/Repo-GGUF:Q4_K_M", ["org/Repo-GGUF", "Q4_K_M"]],
["org/Repo-GGUF:IQ4_XS-3.53bpw", ["org/Repo-GGUF", "IQ4_XS-3.53bpw"]],
["org/Repo-GGUF:UD-Q4_K_XL", ["org/Repo-GGUF", "UD-Q4_K_XL"]],
// A .gguf with no quant token in its name is labelled by its stem, and storage
// lowercases the label while the scanner keeps the filename's casing.
["/models/CustomModel.gguf:custommodel", ["/models/CustomModel.gguf", "custommodel"]],
["/models/CustomModel.gguf:CustomModel", ["/models/CustomModel.gguf", "CustomModel"]],
["C:\\models\\CustomModel.gguf:custommodel", ["C:\\models\\CustomModel.gguf", "custommodel"]],
// A shard suffix is not part of the label.
[
"/models/Custom-00001-of-00003.gguf:custom",
["/models/Custom-00001-of-00003.gguf", "custom"],
],
["/models/Custom-00001-of-00003.gguf:custom-00001-of-00003", null],
// An extensionless .gguf still has a label.
["/models/.gguf:gguf", ["/models/.gguf", "gguf"]],
// A quant token inside the filename wins over the stem.
["/models/tinyllama-Q4_K_M.gguf:q4_k_m", ["/models/tinyllama-Q4_K_M.gguf", "q4_k_m"]],
["/models/tinyllama-Q4_K_M.gguf:tinyllama-q4_k_m", null],
// Only the basename is labelled, never the directories above it.
[
"/models/dir/CustomModel.gguf:custommodel",
["/models/dir/CustomModel.gguf", "custommodel"],
],
["/models/dir/CustomModel.gguf:dir/custommodel", null],
// A colon is legal in a POSIX filename. Neither of these is a variant, and
// reading them as one folds two real files onto a single key.
["/models/foo:Bar.gguf", null],
["/models/foo:bar.gguf", null],
["/models/llama.gguf:Bar.gguf", null],
["/models/llama.gguf:bar.gguf", null],
["/models/CustomModel.gguf:othermodel", null],
["/models/model.gguf:notalabel", null],
["/models/plain.gguf:plain:extra", null],
// A Windows drive letter is not a separator either.
["C:\\models\\foo.gguf", null],
["C:/models/foo.gguf", null],
// Nothing to split.
["org/Repo-GGUF", null],
["/models/foo.gguf", null],
["org/Repo:", null],
[":Q4_K_M", null],
];
test("splitQuantSuffix answers exactly as the backend's split_quant_suffix", () => {
for (const [value, expected] of CASES) {
assert.deepEqual(splitQuantSuffix(value), expected, value);
}
});
test("a .gguf filename carrying a colon is not folded into a variant", () => {
// Two real, distinct files: POSIX allows a colon in a name and is case
// sensitive, so the one-time backfill has to keep their settings apart. The
// variant half of an override key is stored lowercased, so folding these makes
// one key and strands whichever file the backfill reaches second.
const upper = "/models/llama.gguf:Bar.gguf";
const lower = "/models/llama.gguf:bar.gguf";
assert.equal(splitQuantSuffix(upper), null);
assert.equal(splitQuantSuffix(lower), null);
assert.notEqual(modelStorageKey(upper, null), modelStorageKey(lower, null));
});

File diff suppressed because it is too large Load diff