The brief's pain point is opaque load failures: llama-cpp-2's errors
bubble up as raw C++ strings ("cudaMalloc failed: out of memory",
"invalid gguf magic"). A user seeing that has no path to recovery.
New backend command test_llm_model runs a staged diagnostic:
1. Model not downloaded → `not-downloaded` + download hint.
2. File size ≤90% of expected → `incomplete` (stalled download)
+ re-download hint. Matters because llama-cpp-2 can segfault
on truncated GGUF rather than returning cleanly.
3. Requested model already loaded → `ready`, no side effects.
4. Otherwise attempt a real load. On failure, classify_llm_load_error
maps the raw string to one of:
- load-failed-vram (OOM / cudaMalloc / allocation)
- load-failed-corrupt (GGUF magic / unsupported format)
- load-failed-permission (permission denied / access denied)
- load-failed-other (catch-all)
Each category has a prewritten actionable hint pointing at the
specific Settings surface (tier picker, re-download, file perms).
classify_llm_load_error is pure-string and unit-tested — 8 cases
covering the main categories plus edge cases (OOM alias, Windows
"Access is denied", unknown errors). Ordered narrow-to-broad so
overlap doesn't misclassify.
Settings UI gets a "Test" button in the AI section's action row,
visible whenever the model is downloaded (both downloaded-idle and
loaded states). Shows inline hint below the status line when the
test surfaces one. Refreshes both local and global LLM status after
the test since a successful test implicitly loads the model.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>