fix(providers): add Qwen model-level thinking style mapping (#5023)
Add _QWEN_THINKING_MODELS to _MODEL_THINKING_STYLES with enable_thinking style. Prevents Qwen 3.5/3.6/3.7 models from exposing raw reasoning content in chat responses. Closes #4934
This commit is contained in:
@@ -99,9 +99,20 @@ _THINKING_STYLE_MAP: dict[str, Any] = {
|
||||
_GATEWAY_REASONING_STYLE_MAP: dict[str, Any] = {
|
||||
"reasoning_effort": lambda effort: {"reasoning": {"effort": effort}},
|
||||
}
|
||||
_QWEN_THINKING_MODELS: frozenset[str] = frozenset({
|
||||
"qwen3.7-max",
|
||||
"qwen3.7-plus",
|
||||
"qwen3.6-max-preview",
|
||||
"qwen3.6-plus",
|
||||
"qwen3.6-flash",
|
||||
"qwen3.5-plus",
|
||||
"qwen3.5-flash",
|
||||
})
|
||||
|
||||
_MODEL_THINKING_STYLES: dict[str, str] = {
|
||||
**dict.fromkeys(_KIMI_THINKING_MODELS, "thinking_type"),
|
||||
**dict.fromkeys(_MIMO_THINKING_MODELS, "thinking_type"),
|
||||
**dict.fromkeys(_QWEN_THINKING_MODELS, "enable_thinking"),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1707,6 +1707,28 @@ def test_dashscope_thinking_disabled_for_none_string() -> None:
|
||||
assert "reasoning_effort" not in kw
|
||||
|
||||
|
||||
def test_qwen_thinking_enabled_via_model_level_mapping() -> None:
|
||||
"""Non-DashScope providers (e.g. OpenRouter) must pick up model-level
|
||||
enable_thinking for Qwen models when reasoning_effort is set."""
|
||||
kw = _build_kwargs_for("openrouter", "qwen/qwen3.6-flash", reasoning_effort="medium")
|
||||
assert kw["extra_body"] == {"enable_thinking": True, "reasoning": {"effort": "medium"}}
|
||||
|
||||
|
||||
def test_qwen_thinking_disabled_via_model_level_mapping() -> None:
|
||||
"""reasoning_effort='none' must send enable_thinking: False via model-level
|
||||
mapping on non-DashScope providers. OpenRouter also emits its own
|
||||
reasoning.effort alongside the provider-level thinking control."""
|
||||
kw = _build_kwargs_for("openrouter", "qwen/qwen3.5-flash", reasoning_effort="none")
|
||||
assert kw["extra_body"] == {"enable_thinking": False, "reasoning": {"effort": "none"}}
|
||||
|
||||
|
||||
def test_qwen_no_extra_body_when_reasoning_effort_omitted() -> None:
|
||||
"""Without reasoning_effort the model-level mapping must not inject extra_body
|
||||
on its own — the provider default applies."""
|
||||
kw = _build_kwargs_for("openrouter", "qwen/qwen3.6-flash", reasoning_effort=None)
|
||||
assert "extra_body" not in kw
|
||||
|
||||
|
||||
def test_deepseek_no_backfill_when_reasoning_effort_none_string() -> None:
|
||||
"""reasoning_effort='none' must NOT trigger reasoning_content backfill (thinking inactive)."""
|
||||
spec = find_by_name("deepseek")
|
||||
|
||||
Reference in New Issue
Block a user