From cfb21e7b63b87cd2b1461b11bdf972f05b5f79eb Mon Sep 17 00:00:00 2001 From: Andrew Xia Date: Wed, 15 Oct 2025 14:38:31 -0700 Subject: [PATCH 1/3] initial commit refactor _construct_harmony_system_input_message Signed-off-by: Andrew Xia --- vllm/entrypoints/openai/serving_responses.py | 80 +++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/vllm/entrypoints/openai/serving_responses.py b/vllm/entrypoints/openai/serving_responses.py index 6cdabff6e709..0ca91f154638 100644 --- a/vllm/entrypoints/openai/serving_responses.py +++ b/vllm/entrypoints/openai/serving_responses.py @@ -849,6 +849,47 @@ def _construct_input_messages( messages.extend(request.input) # type: ignore return messages + def _construct_harmony_system_input_message( + self, request: ResponsesRequest, with_custom_tools: bool, tool_types: list[str] + ) -> OpenAIHarmonyMessage: + reasoning_effort = request.reasoning.effort if request.reasoning else None + enable_browser = ( + "web_search_preview" in tool_types + and self.tool_server is not None + and self.tool_server.has_tool("browser") + ) + enable_code_interpreter = ( + "code_interpreter" in tool_types + and self.tool_server is not None + and self.tool_server.has_tool("python") + ) + enable_container = ( + "container" in tool_types + and self.tool_server is not None + and self.tool_server.has_tool("container") + ) + sys_msg = get_system_message( + reasoning_effort=reasoning_effort, + browser_description=( + self.tool_server.get_tool_description("browser") + if enable_browser and self.tool_server is not None + else None + ), + python_description=( + self.tool_server.get_tool_description("python") + if enable_code_interpreter and self.tool_server is not None + else None + ), + container_description=( + self.tool_server.get_tool_description("container") + if enable_container and self.tool_server is not None + else None + ), + instructions=request.instructions, + with_custom_tools=with_custom_tools, + ) + return sys_msg + def _construct_input_messages_with_harmony( self, request: ResponsesRequest, @@ -857,9 +898,7 @@ def _construct_input_messages_with_harmony( messages: list[OpenAIHarmonyMessage] = [] if prev_response is None: # New conversation. - reasoning_effort = request.reasoning.effort if request.reasoning else None tool_types = [tool.type for tool in request.tools] - # Allow the MCP Tool type to enable built in tools if the # server_label is allowlisted in # envs.GPT_OSS_SYSTEM_TOOL_MCP_LABELS @@ -870,41 +909,10 @@ def _construct_input_messages_with_harmony( and tool.server_label in envs.GPT_OSS_SYSTEM_TOOL_MCP_LABELS ): tool_types.append(tool.server_label) - enable_browser = ( - "web_search_preview" in tool_types - and self.tool_server is not None - and self.tool_server.has_tool("browser") - ) - enable_code_interpreter = ( - "code_interpreter" in tool_types - and self.tool_server is not None - and self.tool_server.has_tool("python") - ) - enable_container = ( - "container" in tool_types - and self.tool_server is not None - and self.tool_server.has_tool("container") - ) with_custom_tools = has_custom_tools(tool_types) - sys_msg = get_system_message( - reasoning_effort=reasoning_effort, - browser_description=( - self.tool_server.get_tool_description("browser") - if enable_browser and self.tool_server is not None - else None - ), - python_description=( - self.tool_server.get_tool_description("python") - if enable_code_interpreter and self.tool_server is not None - else None - ), - container_description=( - self.tool_server.get_tool_description("container") - if enable_container and self.tool_server is not None - else None - ), - instructions=request.instructions, - with_custom_tools=with_custom_tools, + + sys_msg = self._construct_harmony_system_input_message( + request, with_custom_tools, tool_types ) messages.append(sys_msg) if with_custom_tools: From a7a6cda0edcec541e591459a95c73811c292665f Mon Sep 17 00:00:00 2001 From: Andrew Xia Date: Wed, 15 Oct 2025 15:31:10 -0700 Subject: [PATCH 2/3] refactor validation Signed-off-by: Andrew Xia --- .pre-commit-config.yaml | 6 +-- tools/pre_commit/mypy.py | 3 ++ vllm/entrypoints/openai/serving_responses.py | 44 ++++++++++++-------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 121bdb750de5..e17d6b2c1aee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: files: ^requirements/test\.(in|txt)$ - id: mypy-local name: Run mypy for local Python installation - entry: python tools/pre_commit/mypy.py 0 "local" + entry: python3.12 tools/pre_commit/mypy.py 0 "local" stages: [pre-commit] # Don't run in CI <<: &mypy_common language: python @@ -105,7 +105,7 @@ repos: types: [python] - id: check-root-lazy-imports name: Check root lazy imports - entry: python tools/check_init_lazy_imports.py + entry: python3.12 tools/check_init_lazy_imports.py language: python types: [python] - id: check-filenames @@ -144,7 +144,7 @@ repos: additional_dependencies: [regex] - id: validate-config name: Validate configuration has default values and that each field has a docstring - entry: python tools/validate_config.py + entry: python3.12 tools/validate_config.py language: python additional_dependencies: [regex] # Keep `suggestion` last diff --git a/tools/pre_commit/mypy.py b/tools/pre_commit/mypy.py index a3aa54634725..71022736b975 100755 --- a/tools/pre_commit/mypy.py +++ b/tools/pre_commit/mypy.py @@ -123,12 +123,14 @@ def mypy( def main(): + print("HLOL") ci = sys.argv[1] == "1" python_version = sys.argv[2] file_groups = group_files(sys.argv[3:]) if python_version == "local": python_version = f"{sys.version_info.major}.{sys.version_info.minor}" + print(f"Using local Python version: {python_version}") returncode = 0 for file_group, changed_files in file_groups.items(): @@ -141,4 +143,5 @@ def main(): if __name__ == "__main__": + print("LOL") sys.exit(main()) diff --git a/vllm/entrypoints/openai/serving_responses.py b/vllm/entrypoints/openai/serving_responses.py index 0ca91f154638..ffc692f09973 100644 --- a/vllm/entrypoints/openai/serving_responses.py +++ b/vllm/entrypoints/openai/serving_responses.py @@ -227,6 +227,29 @@ def _validate_generator_input( ) return None + def _validate_create_responses_input( + self, request: ResponsesRequest + ) -> ErrorResponse | None: + if self.use_harmony and request.is_include_output_logprobs(): + return self.create_error_response( + err_type="invalid_request_error", + message="logprobs are not supported with gpt-oss models", + status_code=HTTPStatus.BAD_REQUEST, + ) + if request.store and not self.enable_store and request.background: + return self.create_error_response( + err_type="invalid_request_error", + message=( + "This vLLM engine does not support `store=True` and " + "therefore does not support the background mode. To " + "enable these features, set the environment variable " + "`VLLM_ENABLE_RESPONSES_API_STORE=1` when launching " + "the vLLM server." + ), + status_code=HTTPStatus.BAD_REQUEST, + ) + return None + async def create_responses( self, request: ResponsesRequest, @@ -240,6 +263,9 @@ async def create_responses( if error_check_ret is not None: logger.error("Error with model %s", error_check_ret) return error_check_ret + maybe_validation_error = self._validate_create_responses_input(request) + if maybe_validation_error is not None: + return maybe_validation_error # If the engine is dead, raise the engine's DEAD_ERROR. # This is required for the streaming case, where we return a @@ -248,18 +274,6 @@ async def create_responses( raise self.engine_client.dead_error if request.store and not self.enable_store: - if request.background: - return self.create_error_response( - err_type="invalid_request_error", - message=( - "This vLLM engine does not support `store=True` and " - "therefore does not support the background mode. To " - "enable these features, set the environment variable " - "`VLLM_ENABLE_RESPONSES_API_STORE=1` when launching " - "the vLLM server." - ), - status_code=HTTPStatus.BAD_REQUEST, - ) # Disable the store option. # NOTE(woosuk): Although returning an error is possible, we opted # to implicitly disable store and process the request anyway, as @@ -267,12 +281,6 @@ async def create_responses( # (i.e., their request's `store=True` just because it's the default # value). request.store = False - if self.use_harmony and request.is_include_output_logprobs(): - return self.create_error_response( - err_type="invalid_request_error", - message="logprobs are not supported with gpt-oss models", - status_code=HTTPStatus.BAD_REQUEST, - ) # Handle the previous response ID. prev_response_id = request.previous_response_id From 63fb87394114c10b95e7fc2a6595f5f5790a5e34 Mon Sep 17 00:00:00 2001 From: Andrew Xia Date: Wed, 15 Oct 2025 15:43:14 -0700 Subject: [PATCH 3/3] revert temp Signed-off-by: Andrew Xia --- .pre-commit-config.yaml | 6 +++--- tools/pre_commit/mypy.py | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e17d6b2c1aee..121bdb750de5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: files: ^requirements/test\.(in|txt)$ - id: mypy-local name: Run mypy for local Python installation - entry: python3.12 tools/pre_commit/mypy.py 0 "local" + entry: python tools/pre_commit/mypy.py 0 "local" stages: [pre-commit] # Don't run in CI <<: &mypy_common language: python @@ -105,7 +105,7 @@ repos: types: [python] - id: check-root-lazy-imports name: Check root lazy imports - entry: python3.12 tools/check_init_lazy_imports.py + entry: python tools/check_init_lazy_imports.py language: python types: [python] - id: check-filenames @@ -144,7 +144,7 @@ repos: additional_dependencies: [regex] - id: validate-config name: Validate configuration has default values and that each field has a docstring - entry: python3.12 tools/validate_config.py + entry: python tools/validate_config.py language: python additional_dependencies: [regex] # Keep `suggestion` last diff --git a/tools/pre_commit/mypy.py b/tools/pre_commit/mypy.py index 71022736b975..a3aa54634725 100755 --- a/tools/pre_commit/mypy.py +++ b/tools/pre_commit/mypy.py @@ -123,14 +123,12 @@ def mypy( def main(): - print("HLOL") ci = sys.argv[1] == "1" python_version = sys.argv[2] file_groups = group_files(sys.argv[3:]) if python_version == "local": python_version = f"{sys.version_info.major}.{sys.version_info.minor}" - print(f"Using local Python version: {python_version}") returncode = 0 for file_group, changed_files in file_groups.items(): @@ -143,5 +141,4 @@ def main(): if __name__ == "__main__": - print("LOL") sys.exit(main())