Refs #83 The first vendor-cloud chat row in agent/models.yml. The provider label is the bare word `deepseek` because pi-catalog/src/hosts.ts keys the direct-DeepSeek behaviour set (max_tokens field, thinking extraBody, thinking-disable mode) off that exact name and off api.deepseek.com; the house `<api> (<host>)` pattern would not match and the row would lose the quirks the endpoint answers to. The key is command-backed (`!cat ~/.config/secrets/deepseek_api_key`, 600), so no sk-… value enters the tracked tree, and the row declares the model card's own pair: contextWindow 1048576 / maxTokens 262144, input [text, image], with the October 2026 peak rate card in cost. Docs move to the new omp-docs/core/deepseek-provider.md, indexed and logged in the same commit.
6.5 KiB
type, title, description, resource, tags, verified, timestamp
| type | title | description | resource | tags | verified | timestamp | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| reference | DeepSeek Platform Provider (deepseek/deepseek-flash) | The vendor-cloud row added to agent/models.yml on 2026-10-29 — why the provider label is the bare word `deepseek`, where its key lives, and the window/maxTokens/cost values it declares. | https://api-docs.deepseek.com/ |
|
2026-10-29 | 2026-10-29 |
DeepSeek Platform Provider (deepseek / deepseek-flash)
agent/models.yml gained its first vendor-cloud chat row on 2026-10-29: DeepSeek's
own hosted API, added alongside the four fleet endpoints and the OpenWebUI WAN
door. Use this page when a deepseek/… selector fails, when the key needs
rotating, or before adding another upstream-vendor row.
omp --model 'deepseek/deepseek-flash:off'
Why the label is the bare word deepseek
The house pattern for provider labels is <api> (<host>) — llamacpp (dankclaw),
openwebui (franksdank.cloud). This row breaks it deliberately: the harness
resolves a provider's behaviour set by matching the label (and the baseUrl)
against the catalog's host table, pi-catalog/src/hosts.ts, whose entry reads
/** DeepSeek's first-party API only — gates direct-API quirks (max_tokens field, thinking extraBody). */
deepseekDirect: { providers: ["deepseek"], urlMarkers: ["api.deepseek.com"] },
A label of deepseek (platform) matches neither the provider list nor the URL
marker rule for the name, and the row loses the direct-DeepSeek quirks the
catalog gates behind that key — the max_tokens field name, the thinking
extraBody, and the thinking-disable mode, which on this provider must be
zai-thinking-disabled (thinking: {"type":"disabled"}), not the
none-effort the LAN rows need. The baseUrl carries the host the label
cannot name.
The same table is why the provider's roster is not one row but four. A models.yml
entry is an overlay on the built-in catalog, keyed by provider/id
(#mergeCustomModels → mergeByModelKey), so omp models deepseek now prints:
| Row | Source |
|---|---|
deepseek-flash |
the authored row — 1M context, 262K max-out |
deepseek-v4-flash |
built-in catalog row, untouched |
deepseek-v4-flash-vision-exp |
built-in catalog row, untouched |
deepseek-v4-pro |
built-in catalog row, untouched |
The other three keep catalog windows and pricing; adding a model to the file does not replace the provider.
What the row declares, and from where
| Field | Value | Authority |
|---|---|---|
baseUrl |
https://api.deepseek.com/v1 |
official docs, OpenAI base_url |
api |
openai-completions |
same |
id |
deepseek-flash |
official model name — deepseek-v4-flash / deepseek-v4-flash-vision-exp are retired aliases that route to DeepSeek-V4.1-Flash-1017 and bill at the Flash price |
contextWindow |
1048576 |
model card (context_window 1M) |
maxTokens |
262144 |
model card (max_tokens ≥ 256K) |
input |
[text, image] |
V4.1 is natively image-text-to-text |
cost |
0.3 / 1.2 / 0.006 / 0 per 1M (in / out / cache-read / cache-write) |
October 2026 rate card, peak tier |
compat.supportsToolChoice |
false |
V4 thinking mode rejects the tool_choice parameter; tool calls still work and default to auto |
compat.supportsDeveloperRole |
false |
V4 has no developer role |
compat.reasoningContentField |
reasoning_content |
same field every fleet engine uses |
compat.extraBody.thinking |
{type: enabled} |
the documented request shape |
Laws worth carrying forward:
maxTokensandcontextWindoware a pair. The serving contract isprompt + max_tokens ≤ contextWindow; the harness clampsmax_tokens = min(maxTokens, contextWindow − est − 4096), so a declared pair that exceeds the engine's own contract turns into a 400 rather than a truncation.1048576 / 262144is the pair the card itself states, and it is the pair the row declares.- Cost rates go on the row or nowhere.
costis optional in the schema, and a custom row that omits it reports$0in the status line forever. The schema models one rate per direction, so the off-peak tier ($0.15 / $0.60) cannot be expressed — peak is the value. - Sampling. The card recommends
temperature 1.0 / top_p 1.0; thinking mode floorstop_pat 0.95 server-side, andtop_kis not accepted through the OpenAI surface. The row pinstemperature: 1.0+top_p: 1.0anyway —extraBodyis merged last and wins, so pinning it survives a server-side sampler edit, exactly as the LAN rows do. - A row behind a proxy or a vendor façade copies its direct twin's compat
block; this row has no LAN twin, so it copies the harness's own built-in
descriptor for the same provider (
pi-catalog/src/provider-models/openai-compat.ts,openAiCompletionsDescriptor("deepseek", …)) instead of inventing one.
The key
apiKey: "!cat ~/.config/secrets/deepseek_api_key" — 600-mode file, same
convention as gitea, kagi_api_key, hf_token, and openwebui_api_key. The
rules are the ones in WAN Model Access: a
literal sk-… in the tracked file trips the pre-commit shape gate, and a quoted
!cmd value is the only shape that both resolves and stays out of the gate's
assignment scan. Rotation is rewrite-then-restart; the resolved value is cached
for the process lifetime. Every workstation that pulls this repo needs its own
copy — nothing in the repo carries the value.
Verification performed 2026-10-29
omp models --no-extensionsfrom a scratchHOMEcontaining the editedmodels.yml+config.yml: zerovalidation failedlines, all four fleet providers still listed,deepseek (4)present withdeepseek-flash 1M/262K.- Live call through the scratch
HOME— the only proof that auth came from the newapiKeyline and not from~/.omp/agent/auth.json:omp --model 'deepseek/deepseek-flash:off' … -p 'Reply with exactly the word OK'→OKin 2.6 s. The same scratch tree with thebaseUrlport poisoned to:9hangs instead of answering, which is what rules out a cached or built-in answer.
See also
- WAN Model Access — the credential law and the
off-network route to Frank's own engines;
deepseekis reachable from anywhere but is not that door. - Core config — the rest of
agent/config.yml/models.yml. - OMP Subagent Limits —
providers.maxInFlightRequestsis set per provider id; thedeepseekrow currently has no cap.