4.6 KiB
@deepseek-ai/dsh-client-ui-models
English | 中文
Models settings plugin: the provider configuration page and official-DeepSeek conditional onboarding step. It joins three wire domains into one shared snapshot — llm.providers (the configurable-provider directory with each route's live/dormant state), settings.describe (serialized schemas, layered redacted values, secret slots), and credentials.describe (value-free configured/source/writable badges) — and renders provider rows with one editor card at a time.
Rows are the configured providers (their profile resolves in the owning namespace); a whole-section provider whose key is not configured anywhere (the first-run DeepSeek posture) renders as its open setup card instead of a row, and the add flow is a card carrying the dormant-directory provider select — a bare-mounted llm-pi-ai offers its whole installed catalog before any route exists. The editor is a hand-written card per adapter family: the primary field is a single API key input — the page never asks for an environment-variable name; a typed key stores write-only through credentials.set under the profile's reference, deriving <ROUTE>_API_KEY when the profile has none, and the pi-ai profile records that derivation as apiKeyEnv, so settings.yaml never carries a key value. The collapsed 自定义设置 fold carries the curated extras — baseURL for both families (the deepseek placeholder shows the public endpoint), plus reasoningEffort (deepseek) or reasoning (pi-ai); every other profile field stays owned by settings.yaml. A row is deletable only when the user layer alone carries it (removal restores the composition base).
The DeepSeek step projects deepseek-official readiness from that same joined snapshot after earlier onboarding steps complete. A configured literal apiKey secret sidecar or configured credential reference completes the step without rendering, including a read-only launch-environment credential. A mounted adapter with a missing writable reference shows one action that opens Settings on the Models section, whose existing setup card exclusively owns key input and credentials.set; the step never holds a secret. An absent adapter is skipped because browser navigation cannot mount Cordis plugins, while an unusable settings or credential capability produces a deployment diagnostic with the same route to Models.
Every edit lands as settings.mutate path ops against the stored section — a set per changed field, an unset per cleared one, and a single unset for a deleted row. The page only ever holds the REDACTED descriptor, so it names the fields it can see rather than rebuilding a section: a stored literal secret it never received is mentioned by no op and survives. Each write carries the revision the card opened at, so a concurrent write from another tab or an external settings.yaml edit is refused as settings-conflict and the card asks the user to reopen instead of replaying its stale snapshot. The page refetches on the pushed invalidations (settings/changed, credentials/changed, models/changed, and connection/reset) once it has loaded, so an external settings.yaml edit, a second tab, or a settings-born route converges without polling.
Model Experience
None, as the section renders a browser configuration UI; nothing here reaches a model request.
KV Cache effect
None; this package neither assembles nor sends a provider request.
Known Limitations and Deferred Work
- Only the API key and the curated fold fields are editable on the card — the hand-written editor traded schema-generic field coverage for the mockup layout (Agent Note); advanced fields (
models, retry policy, timeouts…) are edited insettings.yaml, which the fold points at. A profile schema without the conventional fields renders the hint alone, and the two curated layouts key on thellm-deepseek/llm-pi-ainamespaces by name. - Deleting a row leaves its stored key in
.env— removal unsets the settings profile but deliberately does not unset the derived credential; re-adding the provider finds the key already configured. An explicit key-removal control is deferred. - No per-provider model listing on the page — the picker surfaces models; this page shows route state only. A models preview per row is deferred until a consumer needs it.
- Undeclared live routes render nowhere — a route registered without a configurable-provider declaration has no settings address; it stays visible in pickers but not on this page's rows.