1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! DeepSeek thinking-knob resolution.
//!
//! DeepSeek is not a built-in provider: it is reached only through a custom
//! OpenAI-compatible entry whose `base_url` or model id names it. So both the
//! host check and the model check have to recognise it, the same way the qwen
//! path does for gateways that re-serve those models (#1040).
//!
//! Its controls are its own, and are NOT the DashScope ones:
//!
//! - `thinking: {"type": "enabled" | "disabled"}` at the TOP LEVEL of the
//! request body, not inside `extra_body`.
//! - `reasoning_effort` on a `low | high | max` ladder. There is no `xhigh`;
//! that rung belongs to qwen3.8-max.
//! - Off is not a rung. It is `thinking: {"type": "disabled"}` with no effort
//! field at all, so `off` never reaches the wire as an effort value.
//!
//! Sending DashScope's `enable_thinking` to a DeepSeek endpoint is not a
//! no-op with a different name: the field is ignored, the knob DeepSeek reads
//! goes unset, and thinking silently runs at the server default instead of
//! what the user configured. That is the same failure the qwen families had.
/// The effort ladder DeepSeek accepts on the wire.
const WIRE_EFFORTS: = ;
/// Applied when a DeepSeek target has no configured effort. `high` is the
/// vendor default, so an unconfigured install lands there rather than on
/// whatever the endpoint happens to choose. An explicit value always wins.
const DEFAULT_EFFORT: &str = "high";
/// What a request should carry for thinking.
pub
/// Hosts operated by DeepSeek. Only used to recognise a DeepSeek target when
/// the model id does not say so; deliberately NOT the sole gate, because the
/// same models are served by other OpenAI-compatible gateways.
/// Does this model id name a DeepSeek model?
///
/// Checked on the vendor-stripped, lowercased id so a namespaced
/// `deepseek/deepseek-v4-pro` or `SomeVendor/DeepSeek-V4-Flash` is recognised
/// rather than missed for carrying a prefix.
/// Is this request bound for a DeepSeek model?
///
/// Either signal is enough: the id names it, or the endpoint does. A local
/// runtime is excluded, which is the same carve-out the qwen path makes:
/// llama.cpp and MLX serving a DeepSeek GGUF accept neither knob.
pub
/// Resolve the configured knobs into what the wire should carry.
///
/// `configured_effort` is the provider's `reasoning_effort` and
/// `configured_enable_thinking` its `enable_thinking`. The latter is
/// DashScope's spelling, but a user who set it meant "thinking off", and
/// honouring it here is what keeps an explicit off from silently becoming
/// the server default.
pub
/// Context capacity DeepSeek documents for its current models. Used only when
/// the user configured none, so an entry added without a `context_window` gets
/// the vendor's figure instead of the generic fallback. An explicit value in
/// config always wins.
pub const DEFAULT_CONTEXT_WINDOW: u32 = 1_000_000;
// No output cap is defined here on purpose. When the caller sets no
// `max_tokens` we send no cap at all, so DeepSeek applies its own default;
// hard-coding the vendor's current figure would override that default rather
// than match it, and would go stale the day they change it.
/// The vendor default context window for a DeepSeek model, or `None` when the
/// model is not one. Deliberately keyed on the model rather than the endpoint:
/// a gateway serving DeepSeek alongside other families must not hand this
/// figure to the others.
pub