Skip to content

Commit 3c670d5

Browse files
committed
[Bugfix]: Fix the incompatibility issue with tool_choice 'required' when Thinking is enabled
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
1 parent 063844c commit 3c670d5

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

tests/entrypoints/openai/test_completion_with_function_calling.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ...utils import RemoteOpenAIServer
99

1010
# any model with a chat template should work here
11-
MODEL_NAME = "Qwen/Qwen2.5-1.5B-Instruct"
11+
MODEL_NAME = "Qwen/Qwen3-0.6B"
1212

1313

1414
@pytest.fixture(scope="module")

vllm/entrypoints/openai/serving_chat.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ def extract_tool_call_required_streaming(
323323
delta_text: str,
324324
function_name_returned: bool,
325325
) -> tuple[Optional[DeltaMessage], bool]:
326+
if current_text is None or current_text == "":
327+
# if the current text is empty, we cannot parse it
328+
return None, function_name_returned
326329
try:
327330
obj = partial_json_parser.loads(current_text)
328331
except partial_json_parser.core.exceptions.MalformedJSON:
@@ -649,10 +652,18 @@ async def chat_completion_stream_generator(
649652
current_text = previous_text + delta_text
650653
fn_name_returned = function_name_returned[i]
651654

655+
if self.reasoning_parser:
656+
_, content = \
657+
reasoning_parser.extract_reasoning_content(
658+
current_text,
659+
request
660+
)
661+
else:
662+
content = current_text
652663
delta_message, function_name_returned[i] = (
653664
self.extract_tool_call_required_streaming(
654665
previous_text=previous_text,
655-
current_text=current_text,
666+
current_text=content,
656667
delta_text=delta_text,
657668
function_name_returned=fn_name_returned))
658669

@@ -932,8 +943,7 @@ async def chat_completion_full_generator(
932943
else:
933944
logprobs = None
934945
auto_tools_called = False
935-
reasoning_content = None
936-
content = output.text
946+
937947
if self.reasoning_parser:
938948
try:
939949
reasoning_parser = self.reasoning_parser(tokenizer)
@@ -945,6 +955,9 @@ async def chat_completion_full_generator(
945955
reasoning_content, content = (
946956
reasoning_parser.extract_reasoning_content(
947957
output.text, request=request))
958+
else:
959+
reasoning_content = None
960+
content = output.text
948961

949962
# if auto tools are not enabled, and a named tool choice using
950963
# outlines is not being used
@@ -978,6 +991,7 @@ async def chat_completion_full_generator(
978991

979992
# the fields of FunctionDefinition are a superset of the
980993
# tool call outputs and can be used for parsing
994+
assert content is not None
981995
tool_calls = TypeAdapter(
982996
list[FunctionDefinition]).validate_json(content)
983997
message = ChatMessage(

0 commit comments

Comments
 (0)