Models are the first thing you configure and the thing DSH makes most replaceable: the same session machinery answers whether your key belongs to DeepSeek, a catalog provider, or a self-hosted gateway. This guide walks the official providers guide (docs/user/guide/providers.md, fetched at write time) and adds the why behind each step.
DeepSeek: one key field
Open Settings → Models. The DeepSeek card exposes one API-key field; enter the key and save. Two properties are worth internalizing from the official guide:
- Keys are write-only. The page receives a redacted descriptor after saving, never the literal secret.
- Storage is split by design. The key lives in
$DSH_HOME/.credentials.yaml; settings retain only its credential reference.
Catalog providers: the fast path
Choose Add provider and pick from the installed catalog — Anthropic, OpenAI and friends. The catalog supplies the endpoint, protocol and model list, so a key is all you enter. The exception the official guide calls out: providers with native authentication — Bedrock (AWS credentials + region), Vertex (ADC project), Azure (api-version), Codex (OAuth) — need their native credentials; filling only the API-key field does not configure them.
Custom providers: any OpenAI-compatible gateway
Choose Add a custom provider for a company gateway, self-hosted server, or anything absent from the catalog. The form takes a lowercase Provider ID, base URL, API protocol, credential and at least one model.
Two form behaviors matter:
- The Provider ID is permanent — requests, saved sessions, model defaults and credential references all use it. Renaming = add new, delete old.
- Fetch available models queries the base URL and credential currently in the form; selecting candidates only updates the draft, and nothing is stored until you save.
Image input: one line, then it works
A hand-entered model is treated as text-only until it declares otherwise — nothing can ask an endpoint which modalities it accepts, so attaching an image is refused before it is sent. The fix is one line in $DSH_HOME/settings.yaml, because the form has no field for it:
llm-pi-ai:
providers:
my-gateway:
models:
- id: vision-preview
input: [text, image]
input applies to that model alone. For a route where every model takes images, set defaultInput: [text, image] once on the route instead — it is a fallback, not an override, so it never removes images from a catalog model that already has them.
Request compatibility: the two switches that fix most gateways
A gateway can hold a working key at a reachable address and still refuse every request. The official guide explains why: request shape is decided from the endpoint’s URL, and an unrecognized address is treated as OpenAI itself — while most OpenAI-compatible gateways refuse at least one thing OpenAI accepts. Two differences account for most of it:
- Reasoning-capable models get their system prompt sent as
role: "developer"— many gateways reject the role outright. - The output cap is sent as
max_completion_tokens— servers that only knowmax_tokensrefuse it.
Neither has a form field. Correct them on the route:
llm-pi-ai:
providers:
my-gateway:
compat:
supportsDeveloperRole: false
maxTokensField: max_tokens
compat on the route is the default for its models; a model’s own compat wins field by field. Both fields state a claim about your endpoint rather than checking it — and every switch you name needs a value, because an empty key is refused rather than ignored.
Model selection semantics
Configured providers appear in the model picker; selecting a model also makes it the default for new sessions. Sessions that have already sent a request keep the model recorded in their own log — so switching defaults never rewrites history. If a saved default names a deleted provider, the composer shows Select model and blocks input until another model is chosen.
Troubleshooting, condensed
The official guide’s table, in one line each:
MISSING_CREDENTIAL→ store the key via the Models page or the referenced env varUNKNOWN_MODEL→ select a configured model or add the missing one- Model discovery 401 → check the key; enter models manually for endpoints without
GET /models - Gateway refuses everything though key and URL are right → the two
compatswitches above - Only reasoning models fail →
compat.supportsDeveloperRole: false - Image refused before sending → the model declares no image modality; add
input: [text, image] - Provider rejects a request carrying an image → the declared image modality is a claim, not a check; remove
imageand start a new session
Where this fits with the rest of the site
- Quick start — get the Web UI running first
- Profiles and the dsh plugin Command — how provider settings relate to profiles
- What is DeepSeek Harness? — the architecture primer
- The map — the stock routes are text-only (the official guide says DeepSeek’s own chat-completions route cannot be configured otherwise), which is the gap vision tools like ModLens and DSH Vision Toolkit fill; both are indexed there
- Stats — live build-time counts