diff --git a/python/sglang/srt/function_call/deepseekv31_detector.py b/python/sglang/srt/function_call/deepseekv31_detector.py index cab924544..f9891d96f 100644 --- a/python/sglang/srt/function_call/deepseekv31_detector.py +++ b/python/sglang/srt/function_call/deepseekv31_detector.py @@ -114,13 +114,14 @@ class DeepSeekV31Detector(BaseFormatDetector): calls: list[ToolCallItem] = [] try: partial_match = re.search( - pattern=r"<|tool▁call▁begin|>(.*)<|tool▁sep|>(.*)<|tool▁call▁end|>", + pattern=r"<|tool▁call▁begin|>(.*)<|tool▁sep|>(.*?)(<|tool▁call▁end|>|$)", string=current_text, flags=re.DOTALL, ) if partial_match: func_name = partial_match.group(1).strip() func_args_raw = partial_match.group(2).strip() + is_tool_end = partial_match.group(3) # Initialize state if this is the first tool call if self.current_tool_id == -1: @@ -179,15 +180,9 @@ class DeepSeekV31Detector(BaseFormatDetector): pass # Find the end of the current tool call and remove only that part from buffer - tool_call_end_pattern = ( - r"<|tool▁call▁begin|>.*?<|tool▁call▁end|>" - ) - match = re.search( - tool_call_end_pattern, current_text, re.DOTALL - ) - if match: + if is_tool_end: # Remove the completed tool call from buffer, keep any remaining content - self._buffer = current_text[match.end() :] + self._buffer = current_text[partial_match.end(3) :] else: self._buffer = ""