From b07555d26f4c7ad9a2d1ec45428a9d4287db612c Mon Sep 17 00:00:00 2001 From: Andrew Xia Date: Tue, 25 Nov 2025 10:27:26 -0800 Subject: [PATCH] [responsesAPI][2] parse ResponseFunctionToolCallOutputItem (#29383) Signed-off-by: Andrew Xia Co-authored-by: Andrew Xia --- tests/entrypoints/test_responses_utils.py | 15 +++++++++++++++ vllm/entrypoints/openai/protocol.py | 5 +---- vllm/entrypoints/responses_utils.py | 9 +++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/tests/entrypoints/test_responses_utils.py b/tests/entrypoints/test_responses_utils.py index 91c818374e3fd..893d806b65742 100644 --- a/tests/entrypoints/test_responses_utils.py +++ b/tests/entrypoints/test_responses_utils.py @@ -2,6 +2,9 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import pytest +from openai.types.responses.response_function_tool_call_output_item import ( + ResponseFunctionToolCallOutputItem, +) from openai.types.responses.response_reasoning_item import ( Content, ResponseReasoningItem, @@ -76,6 +79,18 @@ class TestResponsesUtils: == 'Hmm, the user has just started with a simple "Hello,"' ) + tool_call_output = ResponseFunctionToolCallOutputItem( + id="temp_id", + type="function_call_output", + call_id="temp", + output="1234", + status="completed", + ) + formatted_item = construct_chat_message_with_tool_call(tool_call_output) + assert formatted_item["role"] == "tool" + assert formatted_item["content"] == "1234" + assert formatted_item["tool_call_id"] == "temp" + item = ResponseReasoningItem( id="lol", summary=[], diff --git a/vllm/entrypoints/openai/protocol.py b/vllm/entrypoints/openai/protocol.py index 98a385a1dcd5f..688ea9697d9d6 100644 --- a/vllm/entrypoints/openai/protocol.py +++ b/vllm/entrypoints/openai/protocol.py @@ -29,7 +29,6 @@ from openai.types.responses import ( ResponseOutputItemAddedEvent, ResponseOutputItemDoneEvent, ResponsePrompt, - ResponseReasoningItem, ResponseReasoningTextDeltaEvent, ResponseReasoningTextDoneEvent, ResponseStatus, @@ -304,9 +303,7 @@ def get_logits_processors( return None -ResponseInputOutputItem: TypeAlias = ( - ResponseInputItemParam | ResponseReasoningItem | ResponseFunctionToolCall -) +ResponseInputOutputItem: TypeAlias = ResponseInputItemParam | ResponseOutputItem class ResponsesRequest(OpenAIBaseModel): diff --git a/vllm/entrypoints/responses_utils.py b/vllm/entrypoints/responses_utils.py index b02c43c7f8246..07abb80ebc9e3 100644 --- a/vllm/entrypoints/responses_utils.py +++ b/vllm/entrypoints/responses_utils.py @@ -10,6 +10,9 @@ from openai.types.chat.chat_completion_message_tool_call_param import ( Function as FunctionCallTool, ) from openai.types.responses import ResponseFunctionToolCall, ResponseOutputItem +from openai.types.responses.response_function_tool_call_output_item import ( + ResponseFunctionToolCallOutputItem, +) from openai.types.responses.response_output_message import ResponseOutputMessage from openai.types.responses.response_reasoning_item import ResponseReasoningItem from openai.types.responses.tool import Tool @@ -94,6 +97,12 @@ def construct_chat_message_with_tool_call( "role": "assistant", "reasoning": reasoning_content, } + elif isinstance(item, ResponseFunctionToolCallOutputItem): + return ChatCompletionToolMessageParam( + role="tool", + content=item.output, + tool_call_id=item.call_id, + ) elif item.get("type") == "function_call_output": # Append the function call output as a tool message. return ChatCompletionToolMessageParam(