@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 8d3f8f485e
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 6, 17:00 UTC

[Bugfix] fix Qwen3.5 tool calling bug (#36774)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>

Chauncey committed Mar 16, 2026 at 15:38 UTC 8d3f8f485efc0b812f91ecf19a3a12232587550c
1 file changed +7 -5
vllm/tool_parsers/qwen3coder_tool_parser.py
+7 -5
@@ -249,7 +249,10 @@ class Qwen3CoderToolParser(ToolParser):
249 self, function_call_str: str, tools: list[ChatCompletionToolsParam] | None
250 ) -> ToolCall | None:
251 # Extract function name
252 - end_index = function_call_str.index(">")
252 + end_index = function_call_str.find(">")
253 + # If there's no ">" character, this is not a valid xml function call
254 + if end_index == -1:
255 + return None
256 function_name = function_call_str[:end_index]
257 param_config = self._get_arguments_config(function_name, tools)
258 parameters = function_call_str[end_index + 1 :]
@@ -316,7 +319,6 @@ class Qwen3CoderToolParser(ToolParser):
319 self._parse_xml_function_call(function_call_str, request.tools)
320 for function_call_str in function_calls
321 ]
319 -
322 # Populate prev_tool_call_arr for serving layer to set finish_reason
323 self.prev_tool_call_arr.clear() # Clear previous calls
324 for tool_call in tool_calls:
@@ -333,10 +335,10 @@ class Qwen3CoderToolParser(ToolParser):
335 idx = model_output.find(self.tool_call_prefix)
336 content_index = content_index if content_index >= 0 else idx
337 content = model_output[:content_index] # .rstrip()
336 -
338 + valid_tool_calls = [tc for tc in tool_calls if tc is not None]
339 return ExtractedToolCallInformation(
338 - tools_called=(len(tool_calls) > 0),
339 - tool_calls=tool_calls,
340 + tools_called=(len(valid_tool_calls) > 0),
341 + tool_calls=valid_tool_calls,
342 content=content if content else None,
343 )
344