Declare provider settings, and give the context figure a denominator

Two things a session could not say, and one it was saying wrongly.

**Every provider setting is reachable.** `-np 1`, the MTP draft depth, the
tool set, the sampling parameters -- most were hardcoded to what measured
best on this machine, which is right as a default and wrong as a constant:
the next machine has a different GPU and a different core count, and
nobody running this app can edit the source. `DriverKind::params` now
declares what a provider takes -- key, label, shape, what blank means, and
whether a change waits for a restart -- and the phone renders whatever
arrives, on the spawn form and in the session settings dialog. Adding a
setting to a driver is one entry in that table and no app change.
`POST /sessions/{id}/params` takes the whole map, so an absent key is the
instruction to unset; the sampling half applies at once and the session is
told in words which of the rest are waiting for a restart.

`tools` is one of them, because it is the biggest lever on a tight
context: the seven built-in definitions are ~1,300 tokens of every prompt
(2,191 against 887 with none). `"none"` omits the flag rather than passing
it on, since `--tools none` is `unknown tool "none"` and a server that
exits.

**The context figure has a denominator.** `Event::ContextWindow` carries
it, read from `llama-server`'s `/props` once the model is up -- the
measurement rather than the request, since a session that named no context
size gets the model's own. Neither coding CLI states its window, so those
keep the bare figure: "2,042" and "2,042 / 8,192" are deliberately
different-looking, and a missing ceiling is never drawn as a proportion of
an assumed one.

**And the numerator was wrong**, by the length of the last reply: it was
the prompt alone, so a five-word answer reported 2,042 against a slot
holding 2,355. It is the turn's total now, which matches `llama-server`'s
own `n_tokens` to within a token.

Two defects the review found, both of which would have shipped: changing
settings on a *stopped* session reported "no process running, so it can't
take new settings", when a stopped session is exactly when you would set
them for the next start; and `GET /tools` answers **403** rather than an
empty list on a server started without `--tools`, so reading it as a
failure made the no-tools session one that never started.

Verified against real models: settings spawned and changed live, the
restart note, a session with two tools and one with none, and the counter
checked against the server's own slot occupancy each time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-19 13:58:08 -04:00
1 parent ac476ab0c9
commit 81ab564a09
18 files changed
+831 -115

No files matched your search

+14 -1
View File
@@ -15,7 +15,7 @@ use std::path::Path;
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use super::driver::{Event, SessionStatus, context_after};
use super::driver::{Event, SessionStatus, context_after, context_limit_after};
/// One transcript line: an [`Event`] plus its position and time. The event
/// is flattened so the wire shape stays one flat object.
@@ -34,6 +34,7 @@ pub struct Transcript {
last_status: Option<SessionStatus>,
last_activity: Option<f64>,
context_tokens: Option<u64>,
context_limit: Option<u64>,
}
impl Transcript {
@@ -68,6 +69,12 @@ impl Transcript {
context_tokens: existing
.iter()
.fold(None, |current, entry| context_after(current, &entry.event)),
// The same fold for the same reason: a session whose process has
// since exited has no window, and the newest `ContextWindow` line
// alone would not know that.
context_limit: existing.iter().fold(None, |current, entry| {
context_limit_after(current, &entry.event)
}),
})
}
@@ -107,6 +114,12 @@ impl Transcript {
self.context_tokens
}
/// What that figure is out of, as of opening, and `None` where this
/// session's provider does not say.
pub fn context_limit(&self) -> Option<u64> {
self.context_limit
}
/// Appends `event`, assigning it the next sequence number. Flushed per
/// event: each line is tiny, and the transcript is the source of truth a
/// crash must not lose the tail of.