Skip to content

[Bug] DeepSeek 思考档位「最高」与「高」发出相同的 reasoning_effort,max 映射缺失 #361

Description

@xiaYuTian11

Affected area

Model providers

Version or commit

v1.2.3 (desktop release); defect confirmed in source at main@7de95a20

Environment

OS: Windows (desktop app)
Deployment: desktop app (pre-compiled release)
Provider: OpenAI-compatible relay, provider type = codex
Models: deepseek-v4-pro / deepseek-v4-flash

Steps to reproduce

  1. Configure an OpenAI-compatible (codex type) provider whose activeModels include deepseek-v4-pro or deepseek-v4-flash.
  2. Select deepseek-v4-pro in the chat model picker.
  3. Enable thinking with the 💡 toggle in the composer bar, then open the ✨ reasoning dropdown (composer-reasoning-trigger). Only two levels are offered: 高 (high) and 最高 (max).
  4. Send a message with 高 selected and capture the outgoing request payload.
  5. Send a message with 最高 selected and capture the outgoing request payload.

Expected behavior

The two levels should produce different reasoning_effort values, since the model catalog declares both as supported:

// crates/agent-gui/src/lib/models/catalog.generated.ts
{ id: "deepseek-v4-flash", thinking: { levels: ["high", "max"], off: true } },
{ id: "deepseek-v4-pro",   thinking: { levels: ["high", "max"], off: true } },

Selecting 最高 should send reasoning_effort: "max".

Actual behavior

Both levels send reasoning_effort: "high". The 最高 option has no effect — DeepSeek models effectively have only one usable thinking level.

Root cause is in crates/agent-gui/src/lib/providers/deepSeekProviderAdapter.ts. The catalog declares max, but the adapter only recognises xhigh:

export const DEEPSEEK_THINKING_LEVEL_MAP = {
  minimal: "high",
  low: "high",
  medium: "high",
  high: "high",
  xhigh: "max",   // no `max` entry
};

export function mapDeepSeekReasoningEffort(reasoning) {
  if (!reasoning) return undefined;
  return reasoning === "xhigh" ? "max" : "high";  // `max` falls through to "high"
}

xhigh is never selectable because the catalog does not declare it, so the max → max path is unreachable and every level collapses to "high".

The catalog and the adapter are two files in the same release bundle, so this is a constructive mismatch rather than a configuration problem — no user-side setting can work around it.

Three call sites are affected:

Call site Field Current Expected
normalizeDeepSeekOpenAIPayload reasoning_effort "high" "max"
normalizeDeepSeekAnthropicPayload output_config.effort "high" "max"
resolveDeepSeekAnthropicThinkingRuntime (streamByApi.ts) Anthropic thinking runtime effort "high" "max"

Logs / screenshots

Wire payload captured by driving the real streamSimpleByApi + onPayload pipeline (model built via createModelFromConfig, openai-completions stream mocked to intercept the request):

deepseek-v4-pro   UI=high | clampOpenAI=high | wire reasoning_effort=high | thinking={"type":"enabled"}
deepseek-v4-pro   UI=max  | clampOpenAI=max  | wire reasoning_effort=high | thinking={"type":"enabled"}   <-- expected "max"
deepseek-v4-flash UI=high | clampOpenAI=high | wire reasoning_effort=high
deepseek-v4-flash UI=max  | clampOpenAI=max  | wire reasoning_effort=high                                  <-- expected "max"

Note clampOpenAI=max — the level survives catalog clamping intact and reaches the adapter as "max"; it is the adapter's own mapping that discards it.

Adapter-level reproduction:

=== mapDeepSeekReasoningEffort (current) ===
undefined -> undefined
minimal   -> high
low       -> high
medium    -> high
high      -> high
xhigh     -> max
max       -> high     <-- bug

Derived thinkingLevelMap for deepseek-v4-pro, showing the catalog does grant max:

{ minimal: null, low: null, medium: null, high: 'high', max: 'max' }

A fix is prepared — two lines adding the missing max mapping. I will link the PR to this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions