From 1939a6ad2d4cd2022148ac55919253a790591809 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 12 Aug 2026 00:26:13 -0300 Subject: [PATCH] fix(thinking): add deepseek-v4 to thinking model patterns (#6000) * fix(thinking): add deepseek-v4 to thinking model patterns deepseek-v4-flash emits reasoning_content via the API but was not recognized in _THINKING_MODEL_PATTERNS (only deepseek-r1 and deepseek-reasoner were listed). Add the deepseek-v4 prefix so the model is recognized as thinking-capable. The between-round _thinkOpen leakage was separately fixed by PR #5931 (perf(chat): batch live thinking rendering). Related: #3998, #5931 * test(thinking): cover DeepSeek v4 detection --------- Co-authored-by: Alexandre Teixeira Co-authored-by: Alexandre Teixeira <111787685+alteixeira20@users.noreply.github.com> --- src/llm_core.py | 4 ++-- tests/test_llm_core_thinking_models.py | 27 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/test_llm_core_thinking_models.py diff --git a/src/llm_core.py b/src/llm_core.py index dd112cedc..30aff2e47 100644 --- a/src/llm_core.py +++ b/src/llm_core.py @@ -1319,8 +1319,8 @@ _MISTRAL_REASONING_EFFORT = os.getenv("ODYSSEUS_MISTRAL_REASONING_EFFORT", "high # Models that support structured thinking — may output without opening tag _THINKING_MODEL_PATTERNS = ( - "qwen3", "qwq", "deepseek-r1", "deepseek-reasoner", "minimax", - "m2-reap", "gemma", "stepfun", "step-3", "step3", + "qwen3", "qwq", "deepseek-r1", "deepseek-reasoner", "deepseek-v4", + "minimax", "m2-reap", "gemma", "stepfun", "step-3", "step3", "magistral", "mistral-small", "mistral-medium", ) diff --git a/tests/test_llm_core_thinking_models.py b/tests/test_llm_core_thinking_models.py new file mode 100644 index 000000000..4ed4fc3c8 --- /dev/null +++ b/tests/test_llm_core_thinking_models.py @@ -0,0 +1,27 @@ +"""Regression coverage for structured-thinking model detection.""" + +import os + +os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:") + +import pytest + +from src.llm_core import _supports_thinking + + +@pytest.mark.parametrize( + "model", + [ + "deepseek-v4", + "deepseek-v4-flash", + "DeepSeek-V4-Flash", + "deepseek/deepseek-v4-flash", + ], +) +def test_deepseek_v4_models_support_thinking(model): + assert _supports_thinking(model) is True + + +@pytest.mark.parametrize("model", ["deepseek-v3", "deepseek-chat"]) +def test_other_deepseek_models_are_not_promoted_to_thinking(model): + assert _supports_thinking(model) is False