@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 470ad118b6
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 13, 22:00 UTC

[Frontend] Align finish_reason when tool is called with OpenAI (#25054)

Signed-off-by: Sungyoon Jeong <sungyoon.jeong@furiosa.ai> Co-authored-by: Chauncey <chaunceyjiang@gmail.com>

Sungyoon Jeong committed Nov 3, 2025 at 13:21 UTC 470ad118b6238e66094c9a508dea0aaaaf864093
1 file changed +18 -8
vllm/entrypoints/openai/serving_chat.py
+18 -8
@@ -1170,9 +1170,13 @@ class OpenAIServingChat(OpenAIServing):
1170 )
1171
1172 # Send the finish response for each request.n only once
1173 + # In OpenAI's API, when a tool is called, the
1174 + # finish_reason is:
1175 + # "tool_calls" for "auto" or "required" tool calls,
1176 + # and "stop" for named tool calls.
1177 if (
1178 auto_tools_called
1175 - or tools_streamed[i]
1179 + or (tools_streamed[i] and not tool_choice_function_name)
1180 or (self.use_harmony and harmony_tools_streamed[i])
1181 ):
1182 finish_reason_ = "tool_calls"
@@ -1523,18 +1527,24 @@ class OpenAIServingChat(OpenAIServing):
1527 message = ChatMessage(
1528 role=role, reasoning_content=reasoning_content, content=content
1529 )
1530 + # In OpenAI's API, when a tool is called, the finish_reason is:
1531 + # "tool_calls" for "auto" or "required" tool calls,
1532 + # and "stop" for named tool calls.
1533 + is_finish_reason_tool_calls = auto_tools_called or (
1534 + request.tool_choice
1535 + and request.tool_choice == "required"
1536 + and output.finish_reason == "stop"
1537 + )
1538
1539 choice_data = ChatCompletionResponseChoice(
1540 index=output.index,
1541 message=message,
1542 logprobs=logprobs,
1531 - finish_reason=(
1532 - "tool_calls"
1533 - if auto_tools_called
1534 - else output.finish_reason
1535 - if output.finish_reason
1536 - else "stop"
1537 - ),
1543 + finish_reason="tool_calls"
1544 + if is_finish_reason_tool_calls
1545 + else output.finish_reason
1546 + if output.finish_reason
1547 + else "stop",
1548 stop_reason=output.stop_reason,
1549 token_ids=(
1550 as_list(output.token_ids) if request.return_token_ids else None