Faces: Settings > Faces tab and the add-a-model licence dialog

An off-by-default "Recognise faces" toggle and the face model list in Settings,
with a one-drop install: pick a .onnx (Add a model file…) or drop one on the
window. The engine inspects it (recognised by hash, or described from its
shape), a dialog shows its licence, whether commercial use is allowed, what it
was trained on and what LightCraft had to assume, and Install stays disabled
until "I accept" is ticked. "Get…" opens a model's own page in the browser:
LightCraft never fetches a model itself. A file it cannot use says why.

The models folder is shared by the app, the CLI and the MCP server
(`engine::config`, `$LIGHTCRAFT_FACE_MODELS` overrides `<config>/models`), so a
model installed from one is there for the others. A session has none until a host
asks (`with_default_face_models`), which keeps tests hermetic.

Nothing runs a model yet, and the tab says so. Headless tests cover the whole
flow (the dialog, refusing until accepted, installing, a file it cannot use).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
Daniel VoshartandClaude Sonnet 5.5 committed 2026-10-08 21:59:01 -04:00
1 parent 7ca7113b32
commit cb34bb4842
17 files changed
+429 -15

No files matched your search

+3 -3
View File
@@ -734,12 +734,12 @@ fn snapshot(args: &[String]) -> Result<(), String> {
let t0 = Instant::now();
let mut session = match &library {
Some(dir) => {
let mut s = Session::new().with_fs();
let mut s = Session::new().with_fs().with_default_face_models();
s.open_library(dir, false).map_err(|e| library_error(dir, e))?;
s
}
None if files.is_empty() => Session::with_demo().with_fs(),
None => Session::new().with_fs(),
None if files.is_empty() => Session::with_demo().with_fs().with_default_face_models(),
None => Session::new().with_fs().with_default_face_models(),
};
if !files.is_empty() {
let ti = Instant::now();