返回 DeepSeek-Reasonix
REASONING_CONTRACT.md
根目录 / docs / REASONING_CONTRACT.md
1 # Adapter-owned reasoning controls
2
3 Each protocol adapter registers a pure `ReasoningForConfig` resolver alongside
4 its provider factory. Its returned options are ordered IDs with display names and
5 optional descriptions. Core does not impose a global effort vocabulary. Resolved
6 clients expose a detached capability snapshot through `ReasoningProvider`.
7
8 Configuration, the desktop effort menu, CLI completion, the local model catalog,
9 and request validation use these declarations. Model overrides must be resolved
10 before querying capabilities. Extension providers own their declared `Efforts`
11 list; selection and request overrides are validated before sidecar stream I/O.
12
13 Explicit selections must match a declared ID exactly. Unsupported choices return
14 `UNSUPPORTED_REASONING_EFFORT` before network I/O. Missing capability metadata
15 returns `UNKNOWN_MODEL_REASONING` for an explicit choice, with recovery through
16 `auto` or a configured protocol/vocabulary. An empty list alone does not prove
17 that the model cannot think. Explicit `reasoning_protocol = "none"` declares
18 unsupported controls. Invalid declarations are also
19 rejected. No nearest-level mapping is performed. Binary protocols cannot acquire
20 a depth scale merely by listing depth values in `supported_efforts`.
21
22 `auto` remains the existing UI/CLI spelling for clearing an override; it is not an
23 adapter option and does not mean adaptive thinking. Request-level overrides use
24 an empty string to inherit configuration, not the literal `auto`. Existing load
25 normalization of retired stored `off` and letter case is retained. Existing valid
26 IDs and TOML field names remain unchanged. Saved DeepSeek `medium` and `xhigh`
27 values retain their historical `high` wire value when no explicit effort vocabulary
28 is declared; configuration storage is not rewritten. New explicit selections and
29 request overrides still reject undeclared aliases. Other unsupported aliases
30 produce an actionable error. Invalid configured
31 defaults remain visible for validation instead of falling back to another level.
32
33 | Boundary | Compatibility |
34 | --- | --- |
35 | Provider TOML | Existing fields and valid IDs remain readable; no load-time rewrite |
36 | Desktop `EffortInfo.options` | Optional additive metadata; `levels` remains for older clients |
37 | New frontend / older backend | Falls back to the older `levels` field |
38 | Remote model descriptors | Existing `Efforts` declarations remain authoritative |
39 | Provider-visible history | No prompt, tool schema, or reasoning-history rewrite |
40
41 Default requests retain existing serialization. Explicitly changing an effort can
42 change provider cache behavior; the contract itself does not add prompt bytes.
43 The experimental governor checks declared capability before applying its low
44 request override. This change does not copy Harness's request journal architecture.
45
46 `ResolveReasoningEntry` resolves model overrides, connection overrides, then
47 current built-in facts. Built-in defaults match the exact effective request URL,
48 API kind and model ID, including the Token Rhythm `deepseek-flash` alias;
49 renaming a connection does not change this match. An explicit different reasoning
50 protocol owns its vocabulary. UI metadata, startup validation and adapter
51 construction use the same resolved entry. Raw configuration retains only user
52 declarations, so inherited defaults follow catalog updates. Untagged historical
53 declarations remain explicit because their provenance cannot be recovered safely.
54
55 Full configuration writes include backward-readable model capability snapshots.
56 The optional `reasoning_defaults` marker records generated fields and a digest of
57 the reasoning declaration. Current readers peel only untouched generated fields;
58 older readers still see the original protocol/list/default fields. A legacy
59 writer dropping the marker, or changing the declaration without updating its
60 digest, makes those values explicit. Settings delta saves preserve unrelated and
61 unknown fields without materializing unchanged inherited values.
62
63 | Field or format | Old data | Current reader | Previous reader/writer | Result |
64 | --- | --- | --- | --- | --- |
65 | `reasoning_defaults` | Missing means explicit | Untouched marked fields inherit live defaults | Ignores marker; reads snapshot; marker loss preserves values as explicit | Downgrade remains readable |
66 | Model capability `reasoning.state` | Optional | `supported`, `unsupported`, or `unknown` | Ignores additive metadata | Older UI continues using its existing fields |
67 | Remote descriptor `ReasoningUnknown` | Missing means existing declaration semantics | Preserves unknown adapter metadata | Ignores additive flag | Existing `Efforts` remain valid |
68 | Session model/effort | Existing storage fields | Rebinds as one selection on model changes | Same persisted representation | No session migration |
69
70 Session effort belongs to its provider/model identity. Model changes clear
71 inherited effort even when both models accept the same ID; same-model explicit
72 choices remain strict and are never silently clamped. New drafts only inherit
73 effort from the same model. Boot accepts an optional runtime-only `EffortModel`
74 origin for inherited overrides. CLI, Desktop, ACP and serve paths preserve this
75 boundary; `auto` remains available to clear an override with unknown metadata.
76
77 The design is independently implemented for Reasonix, informed by
78 [DeepSeek Harness's adapter-owned reasoning contract](https://github.com/deepseek-ai/deepseek-harness/blob/d347e703908d0406b7a7ef80e3a0e594d86b2215/.agents/notes/implemented/architecture/2026-07-24-adapter-owned-reasoning-effort-capabilities.md).
79 No upstream implementation was copied.
80
80 lines MARKDOWN