Say a transcript's size, name a model by something, and ask before a reload

Five things asked for on the phone, and one trap behind the first of them.

A llama prompt carries `<__media__>` where a picture was, and llama.cpp
pairs each marker with a decoded image when it tokenizes -- so a marker in
words nobody attached a picture to fails the turn, and then fails every
later one, since the conversation is folded out of a transcript that holds
it for good. A model saying the marker back is enough to do it. Every
message with words in it now goes through `without_marker`.

A model's `general.name` is filled in by whatever converted the file, and
`convert_hf_to_gguf.py` fills it from the directory it converted: Prism ML's
Bonsai publishes `general.name = "Hf"`, which is unique and so passed the
label cascade and told a reader nothing. A name is now used only where it
shares a word with the repo or the file it came from; one that does not
drops to the file name.

The model settings dialog and the server card said what a save would cost in
a paragraph under the control, read after the decision if at all. Both ask
instead, in the shape the rest of that screen already uses for Stop and
Delete -- and the dialog's question is asked over the edits, so Cancel comes
back to them.

A field's label was `labelMedium` in the variant colour while every setting
beside it was body text, which on one form read as two ranks of setting.

`GET /sessions/{id}`'s `transcriptFile` now carries the file's size, and the
settings screen draws it beside what this phone has cached.

Checked on the emulator against the sandbox: the labels line up, the row
says "14 kB · 14 kB cached", and both confirmations appear over a loaded
Qwen3-0.6B. `cargo test` 275 passed, clippy and fmt clean, lint clean.
This commit is contained in:
iris-ai committed 2026-09-21 11:59:26 -04:00
1 parent 4b5ed6e398
commit 1aac22bfc9
10 files changed
+291 -52

No files matched your search

@@ -57,12 +57,10 @@ fun LabelledField(
keyboardActions: KeyboardActions = KeyboardActions.Default,
) {
Column(modifier.fillMaxWidth()) {
Text(
label,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(bottom = 2.dp),
)
// Body size in the ordinary text colour, which is what a setting's label is where the
// control beside it is a switch or a picker. Smaller and greyer on the ones that are
// fields reads as two ranks of setting where there is one.
Text(label, modifier = Modifier.padding(bottom = 2.dp))
hint?.let {
Text(
it,