docs(upstream-ledger): L-4 models/list RPC — client-side static mirror is workaround

Adds L-4 note explaining models/list is currently served from a client-side static mirror as a temporary workaround, style aligned with L-1/L-2 entries.

Files: examples/desktop/docs/upstream-ledger.md +74/-0

Mirrors merge 7b6dfc6b on internal test-real branch. Test counts unchanged: 1820 (docs-only).
This commit is contained in:
ZiyaZhang
2026-07-19 08:39:59 -07:00
parent 95b8b2a1af
commit fcbf6ff813

View File

@@ -200,3 +200,77 @@ becomes pure pass-through (roughly 20 lines) — a small doc-only PR at
that point removes the heuristic scan entirely. Until then, the tri-view that point removes the heuristic scan entirely. Until then, the tri-view
tabs read as "here's what the runtime is showing you" (wire signals) and tabs read as "here's what the runtime is showing you" (wire signals) and
"here's what the shell inferred" (heuristic, tooltipped as such). "here's what the shell inferred" (heuristic, tooltipped as such).
---
## L-4 Runtime should expose a `models/list` RPC (shell-side static mirror is workaround)
**Symptom.** The shell has no wire-level way to ask the runtime "which
(adapter × model) pairs are actually registered right now?". A researcher
who wires up a new adapter or ships a plugin that calls
`ctx.llm.registerAdapter(...)` at boot has no way to see that model in
the composer dropdown without also editing shell code. Picking a model
the runtime doesn't know about falls through to a `NO_ADAPTER` error,
which the shell recovers from with a "switch profile" affordance — but
the up-front list is a static mirror maintained by hand.
**Root cause.** No `models/list` (or equivalent) RPC on the wire. The
runtime knows its own adapter/model registry — that's what routes each
`llm/call` to the right adapter — but it never exposes that registry to
the shell. The shell therefore has to guess, and today "guess" means
"copy the yml into a JS map".
**Local workaround.**
- `src/main/profiles.js:230` — `PROFILE_MODELS` is a static map,
`profile name → array of supported model ids`, one entry per row in
`config/*.yml`.
- `src/main/profiles.js:246` — `modelsFor(name)` is the accessor exported
to `main.js`.
- `src/main/main.js:280` — the `profiles:models` IPC handler snapshots
the whole map to the renderer at handshake / profile-switch time.
- `src/renderer/renderer.js:4048` — `renderComposerModel(currentModel)`
uses the mirror to filter the composer dropdown; if the runtime later
reports `NO_ADAPTER` we fall back to the "switch profile" affordance.
- `test/model-profile-guard.test.js` — parses every `config/*.yml`
`models:` field and asserts the yml matches `PROFILE_MODELS` line by
line, so any yml drift trips the test.
Spot the workaround in code review by the `PROFILE_MODELS` literal at
`src/main/profiles.js:230` and by the guard test — both exist purely
because the runtime never told us.
The workaround is intentionally strict: hand-maintained maps drift, so
the guard test locks yml ↔ map. It does **not** cover runtime-time
`registerAdapter` calls; those still surface only as
`NO_ADAPTER`-then-recover.
**Upstream fix (needed).** Expose a `models/list` RPC on the wire:
```
Method: models/list
Params: none
Result: {
models: [
{ id: string, adapter: string, capabilities?: { streaming, thinking, ... } }
]
}
```
Consumer migration in this shell once the RPC lands:
- Add a `runtime:list-models` IPC and call it once at handshake plus on
every profile switch.
- Downgrade `PROFILE_MODELS` to a fallback used only when the RPC is
unavailable (e.g. older runtime).
- Keep `test/model-profile-guard.test.js` — its job becomes narrower
(yml ↔ fallback consistency), still worth having for older-runtime
users.
**Precedent in ledger.** Same shape as L-1 (`presentResult` wire),
L-2 (trace semantic signals), L-3 (artifact blob snapshot): the shell
paints over an information gap the runtime should own, and the fix is a
small wire addition that lets the workaround retire.
**Reference.** PR #374 review comment by @ZiyaZhang —
https://github.com/deepseek-harness/deepseek-harness/pull/374#issuecomment-5016306211