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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user