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 14, 05:30 UTC
[ResponseAPI] Simplify input/output message serialization (#26620)
Signed-off-by: Jialin Ouyang <Jialin.Ouyang@gmail.com>
Jialin Ouyang committed
Oct 13, 2025 at 02:59 UTC
4073c82c4e44b33677e92cf60480fe5bb331aef7
2 files changed
+53
-24
tests/entrypoints/openai/test_response_api_with_harmony.py
+31
@@ -12,6 +12,8 @@ from openai_harmony import (
12
Message,
13
)
14
15
+from vllm.entrypoints.openai.protocol import serialize_message, serialize_messages
16
+
17
from ...utils import RemoteOpenAIServer
18
19
MODEL_NAME = "openai/gpt-oss-20b"
@@ -758,3 +760,32 @@ async def test_output_messages_enabled(client: OpenAI, model_name: str, server):
760
assert response.status == "completed"
761
assert len(response.input_messages) > 0
762
assert len(response.output_messages) > 0
763
+
764
+
765
+def test_serialize_message() -> None:
766
+ dict_value = {"a": 1, "b": "2"}
767
+ assert serialize_message(dict_value) == dict_value
768
+
769
+ msg_value = {
770
+ "role": "assistant",
771
+ "name": None,
772
+ "content": [{"type": "text", "text": "Test 1"}],
773
+ "channel": "analysis",
774
+ }
775
+ msg = Message.from_dict(msg_value)
776
+ assert serialize_message(msg) == msg_value
777
+
778
+
779
+def test_serialize_messages() -> None:
780
+ assert serialize_messages(None) is None
781
+ assert serialize_messages([]) is None
782
+
783
+ dict_value = {"a": 3, "b": "4"}
784
+ msg_value = {
785
+ "role": "assistant",
786
+ "name": None,
787
+ "content": [{"type": "text", "text": "Test 2"}],
788
+ "channel": "analysis",
789
+ }
790
+ msg = Message.from_dict(msg_value)
791
+ assert serialize_messages([msg, dict_value]) == [msg_value, dict_value]
vllm/entrypoints/openai/protocol.py
+22
-24
@@ -2065,6 +2065,26 @@ class ResponseUsage(OpenAIBaseModel):
2065
total_tokens: int
2066
2067
2068
+def serialize_message(msg):
2069
+ """
2070
+ Serializes a single message
2071
+ """
2072
+ if isinstance(msg, dict):
2073
+ return msg
2074
+ elif hasattr(msg, "__dict__"):
2075
+ return msg.to_dict()
2076
+ else:
2077
+ # fallback to pyandic dump
2078
+ return msg.model_dump_json()
2079
+
2080
+
2081
+def serialize_messages(msgs):
2082
+ """
2083
+ Serializes multiple messages
2084
+ """
2085
+ return [serialize_message(msg) for msg in msgs] if msgs else None
2086
+
2087
+
2088
class ResponsesResponse(OpenAIBaseModel):
2089
id: str = Field(default_factory=lambda: f"resp_{random_uuid()}")
2090
created_at: int = Field(default_factory=lambda: int(time.time()))
@@ -2107,35 +2127,13 @@ class ResponsesResponse(OpenAIBaseModel):
2127
# https://github.com/openai/harmony/issues/78
2128
@field_serializer("output_messages", when_used="json")
2129
def serialize_output_messages(self, msgs, _info):
2110
- if msgs:
2111
- serialized = []
2112
- for m in msgs:
2113
- if isinstance(m, dict):
2114
- serialized.append(m)
2115
- elif hasattr(m, "__dict__"):
2116
- serialized.append(m.to_dict())
2117
- else:
2118
- # fallback to pyandic dump
2119
- serialized.append(m.model_dump_json())
2120
- return serialized
2121
- return None
2130
+ return serialize_messages(msgs)
2131
2132
# NOTE: openAI harmony doesn't serialize TextContent properly, this fixes it
2133
# https://github.com/openai/harmony/issues/78
2134
@field_serializer("input_messages", when_used="json")
2135
def serialize_input_messages(self, msgs, _info):
2127
- if msgs:
2128
- serialized = []
2129
- for m in msgs:
2130
- if isinstance(m, dict):
2131
- serialized.append(m)
2132
- elif hasattr(m, "__dict__"):
2133
- serialized.append(m.to_dict())
2134
- else:
2135
- # fallback to pyandic dump
2136
- serialized.append(m.model_dump_json())
2137
- return serialized
2138
- return None
2136
+ return serialize_messages(msgs)
2137
2138
@classmethod
2139
def from_request(