Ask a provider for its models, and let the app update its CLI

The Claude model list was four words in machines.rs, copied into every
machine's config.ron at discovery -- so a model the CLI had gained was
unreachable from the phone, which is how Opus 5.5 came to be invisible.
Every catalog is now read from the provider itself when a picker opens:
Claude Code over its control channel (control_request{subtype:list_models},
the same channel the driver sends set_model down, since the CLI has no
listing command), Codex over app-server, llama.cpp from the GGUFs on its
machine. Echo is the one case config.ron still answers, having nothing to
ask. A row the CLI marks disabled -- a model the installed version is too
old to run -- is dropped rather than offered as a chip that fails.

The reading of each catalog lives in that driver's own module, and
provider_models is one line per driver: core code says which driver to ask
and never what an answer looks like. parse_codex_models moved out for the
same reason.

Beside it, a provider now reports the version of its program and can be
told to update it. The version comes from --version on its own machine,
read from whichever stream carried it but only from a run that exited 0 --
llama-server prints its version to stderr, and so does "command not found".
It is never compared against a latest release, which nothing here can know.
Update runs the driver's own updater, or an updateCommand the config file
names for an install those will not touch; its whole output comes back,
because every install on these machines is package-managed and the
updater's refusal is the sentence worth reading. Nothing on its stdin, so a
password prompt fails rather than hangs.

A catalog that cannot be read no longer fails the whole provider view: that
is exactly the provider somebody came there to update, and refusing the
screen took the version and the Update button away with it.

Verified against a scratch server and on the emulator: the live catalog
(1.06s, disabled row absent), all four providers' versions including the
unknown state, the confirmation and output dialogs, a configured command
returning in 87ms with its stdin closed, and Update correctly disabled for
llama.cpp.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-23 18:32:51 -04:00
1 parent 53fc59a946
commit 7371af8e36
14 files changed
+773 -135

No files matched your search

+23
View File
@@ -175,6 +175,29 @@ Module-by-module intent is in PLAN.md's "Backend layout".
`wc -c` of the partial against the size HuggingFace published, the sha256
it publishes is what makes a resume safe, and a finished download is not a
state: it is a model, in the list beside the one still going.
**A provider's models are asked for at the moment a picker opens**
(2026-09-23, `machines::provider_models`): Claude Code over its control
channel (`control_request{subtype:list_models}`, the same channel the driver
sends `set_model` down -- the CLI has no listing command), Codex over
app-server, llama.cpp from the GGUFs on its machine. The list used to be four
words in `machines.rs` baked into `config.ron` at discovery, so a model the
CLI gained was unreachable from the phone. Two things fall out of it and are
easy to get wrong again -- **the reading of a catalog lives in its driver's
module** and `provider_models` is a line per driver, because core code knowing
what a Claude answer looks like is the session-type branch this project does
not have; and a row the CLI marks `disabled` is dropped, being a model the
installed version is too old to run.
**A provider reports its version and can be told to update itself**
(2026-09-23, `machines::provider_version` / `update_provider`, drawn in
`ProviderScreen.kt`). The version is `--version` on that machine, taken from
whichever stream carried it but **only from a run that exited 0** -- "command
not found" is on stderr too. It is never compared against a latest release,
which nothing here can know. Update runs `DriverKind::update_args` (`claude
update`, `codex update`) or the `updateCommand` a provider's config entry
names, which is config-file only and deliberately not on any route; its whole
output comes back, because every install on these machines is package-managed
and the updater's refusal is the sentence worth reading. Nothing on its stdin,
so a password prompt fails rather than hangs.
Codex is one persistent `codex app-server --stdio` process per session; its
driver uses native turn steering and interruption, persists the protocol
state and thread id, and reads subscription limits through the same CLI