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