Review findings (PR #7473):
- Look up overrides under the concrete load path with its quant, not just the
advertised repo id, so local folders and non-active HF caches are found.
- Carry bare-repo launch flags into the first per-quant save. Auto-switch
prefers the qualified entry, so without this the flags were silently dropped
and no UI could show or restore them. The bare id is only derived when the
suffix looks like a quant, so a Windows drive letter is not split.
- Drop a saved gpu_ids pin that no longer resolves instead of 400ing the whole
load. A pin outlives the machine it was made on.
- Build the displayed API base from getApiBase() on desktop; the Tauri webview
origin is not the API server.
- Keep a partial download's isDownloaded when opening settings, so the loader
still reports download progress.
- Only prefer the loaded quant when the loaded model is this row. Q4_K_M exists
in most repos, so an unguarded match targeted the wrong variant.
Found by simulation:
- A lone surrogate in a chat template raised UnicodeEncodeError on the byte
check, an unhandled 500. Now a validation error, in all three call sites.
- _bounded_int accepted bools as GPU ids, truncated fractional floats, and
raised OverflowError on Infinity, which json.loads accepts.
- api_monitor stored a non-string model verbatim; the monitor page then threw
on toLowerCase and rendered nothing. Coerced at the boundary and the filter
no longer trusts network data.
- The overlay store now uses storage that cannot throw. Safari private mode and
blocked-cookie origins make localStorage throw on access, which broke the
opt-out toggle.