diff --git a/python/sglang/srt/entrypoints/openai/serving_chat.py b/python/sglang/srt/entrypoints/openai/serving_chat.py index 5b38bf78b..0a928e16c 100644 --- a/python/sglang/srt/entrypoints/openai/serving_chat.py +++ b/python/sglang/srt/entrypoints/openai/serving_chat.py @@ -1065,8 +1065,8 @@ class OpenAIServingChat(OpenAIServingBase): request.chat_template_kwargs is not None and request.chat_template_kwargs.get("thinking") is True ) - if self.reasoning_parser in ["qwen3", "glm45"]: - # qwen3 and glm45 are reasoning by default + if self.reasoning_parser in ["qwen3", "glm45", "nano_v3"]: + # qwen3, glm45, and nano_v3 are reasoning by default return ( not request.chat_template_kwargs or request.chat_template_kwargs.get("enable_thinking", True) is True diff --git a/python/sglang/srt/parser/reasoning_parser.py b/python/sglang/srt/parser/reasoning_parser.py index 9317fe77b..6ed8d9582 100644 --- a/python/sglang/srt/parser/reasoning_parser.py +++ b/python/sglang/srt/parser/reasoning_parser.py @@ -274,6 +274,22 @@ class MiniMaxAppendThinkDetector(BaseReasoningFormatDetector): return StreamingParseResult(normal_text=self.think_start_token + text) +class NanoV3Detector(BaseReasoningFormatDetector): + """ + Detector for NanoV3 model. + Uses the same reasoning format as DeepSeek-R1: ()*(.*) + + """ + + def __init__(self, stream_reasoning: bool = True, force_reasoning: bool = False): + super().__init__( + "", + "", + force_reasoning=force_reasoning, + stream_reasoning=stream_reasoning, + ) + + class ReasoningParser: """ Parser that handles both streaming and non-streaming scenarios for extracting @@ -297,6 +313,7 @@ class ReasoningParser: "minimax": Qwen3Detector, "minimax-append-think": MiniMaxAppendThinkDetector, "step3": DeepSeekR1Detector, + "nano_v3": NanoV3Detector, } def __init__(