[Bugfix][Gemma4] Align parser enable_thinking default with template (#52430)

Signed-off-by: lxy-alexander <lxy_alexander@outlook.com> Co-authored-by: Chauncey <chaunceyjiang@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

Alexander Lee committed Aug 18, 2026 at 08:41 UTC d29dc3ab87840aef42129b30825176295ea73b07
3 files changed +31 -9
tests/parser/engine/test_gemma4_streaming_reasoning.py
+14 -5
@@ -170,7 +170,7 @@ def mock_tokenizer():
170
171 @pytest.fixture
172 def parser(mock_tokenizer):
173 - return Gemma4Parser(mock_tokenizer)
173 + return Gemma4Parser(mock_tokenizer, chat_template_kwargs={"enable_thinking": True})
174
175
176 @pytest.fixture
@@ -289,7 +289,10 @@ class TestGemma4PromptOpenReasoning:
289
290 @pytest.fixture
291 def open_reasoning_parser(self, open_reasoning_tokenizer):
292 - return Gemma4Parser(open_reasoning_tokenizer)
292 + return Gemma4Parser(
293 + open_reasoning_tokenizer,
294 + chat_template_kwargs={"enable_thinking": True},
295 + )
296
297 @staticmethod
298 def _prompt_ids_open_channel() -> list[int]:
@@ -394,7 +397,9 @@ class TestGemma4PreInitReasoningRobustness:
397
398 @pytest.fixture
399 def pre_init_parser(self, pre_init_tokenizer):
397 - return Gemma4Parser(pre_init_tokenizer)
400 + return Gemma4Parser(
401 + pre_init_tokenizer, chat_template_kwargs={"enable_thinking": True}
402 + )
403
404 def test_model_emitted_channel_open_after_new_turn(
405 self, pre_init_parser, pre_init_tokenizer, request_obj
@@ -489,7 +494,9 @@ class TestGemma4ChannelLessOutputConsistency:
494
495 @pytest.fixture
496 def plain_parser(self, plain_tokenizer):
492 - return Gemma4Parser(plain_tokenizer)
497 + return Gemma4Parser(
498 + plain_tokenizer, chat_template_kwargs={"enable_thinking": True}
499 + )
500
501 def test_streaming_channel_less_output_is_content(
502 self, plain_parser, plain_tokenizer, request_obj
@@ -521,7 +528,9 @@ class TestGemma4ChannelLessOutputConsistency:
528 assert reasoning is None
529 assert content == _PLAIN_ANSWER_TEXT
530
524 - stream_parser = Gemma4Parser(plain_tokenizer)
531 + stream_parser = Gemma4Parser(
532 + plain_tokenizer, chat_template_kwargs={"enable_thinking": True}
533 + )
534 results = _stream_tokens_batched(
535 stream_parser,
536 plain_tokenizer,
tests/reasoning/test_gemma4_reasoning_parser.py
+16 -3
@@ -262,14 +262,27 @@ def test_gemma4_adjust_request(generic_tokenizer):
262 assert result is request
263
264
265 -def test_gemma4_previous_turn_reasoning_is_reasoning_end(generic_tokenizer):
265 +@pytest.mark.parametrize(
266 + ("chat_template_kwargs", "expected_is_reasoning_end"),
267 + [
268 + pytest.param({}, True, id="omitted_enable_thinking"),
269 + pytest.param({"enable_thinking": False}, True, id="thinking_disabled"),
270 + pytest.param({"enable_thinking": True}, False, id="thinking_enabled"),
271 + ],
272 +)
273 +def test_gemma4_new_turn_reasoning_end_matches_enable_thinking(
274 + generic_tokenizer,
275 + chat_template_kwargs,
276 + expected_is_reasoning_end,
277 +):
278 output = (
279 "<|channel>thought\n1st thought<channel|>1st content<turn|>\n"
280 "<|turn>user\nThanks<|turn>model\n"
281 )
282 output_tokens = gemma4_encode_output(generic_tokenizer, output)
283 parser: ReasoningParser = ReasoningParserManager.get_reasoning_parser(parser_name)(
272 - generic_tokenizer
284 + generic_tokenizer,
285 + chat_template_kwargs=chat_template_kwargs,
286 )
287 is_reasoning_end = parser.is_reasoning_end(output_tokens)
275 - assert not is_reasoning_end
288 + assert is_reasoning_end is expected_is_reasoning_end
vllm/parser/gemma4.py
+1 -1
@@ -400,7 +400,7 @@ class Gemma4Parser(ParserEngine):
400 **kwargs,
401 ) -> None:
402 chat_kwargs = kwargs.get("chat_template_kwargs", {}) or {}
403 - self._thinking_enabled = chat_kwargs.get("enable_thinking", True)
403 + self._thinking_enabled = chat_kwargs.get("enable_thinking", False)
404 super().__init__(
405 tokenizer,
406 tools,