Merge pull request #21557 from SherifWaly/sherif.waly/add-reasoning-multi-turn-hosted-vllm

Convert thinking_blocks to content blocks for hosted_vllm multi-turn
This commit is contained in:
Sameer Kankute
2026-02-19 18:56:09 +05:30
committed by GitHub
2 changed files with 113 additions and 2 deletions
@@ -137,10 +137,29 @@ class HostedVLLMChatConfig(OpenAIGPTConfig):
self, messages: List[AllMessageValues], model: str, is_async: bool = False
) -> Union[List[AllMessageValues], Coroutine[Any, Any, List[AllMessageValues]]]:
"""
Support translating video files from file_id or file_data to video_url
Support translating:
- video files from file_id or file_data to video_url
- thinking_blocks on assistant messages to content blocks
"""
for message in messages:
if message["role"] == "user":
if message["role"] == "assistant":
thinking_blocks = message.pop("thinking_blocks", None) # type: ignore
if thinking_blocks:
new_content: list = [
{"type": block["type"], "thinking": block.get("thinking", "")}
if block.get("type") == "thinking"
else {"type": block["type"], "data": block.get("data", "")}
for block in thinking_blocks
]
existing_content = message.get("content")
if isinstance(existing_content, str):
new_content.append(
{"type": "text", "text": existing_content}
)
elif isinstance(existing_content, list):
new_content.extend(existing_content)
message["content"] = new_content # type: ignore
elif message["role"] == "user":
message_content = message.get("content")
if message_content and isinstance(message_content, list):
replaced_content_items: List[
@@ -165,3 +165,95 @@ def test_hosted_vllm_supports_thinking():
drop_params=False,
)
assert optional_params["reasoning_effort"] == "low"
def test_hosted_vllm_thinking_blocks_prepended_to_assistant_content():
"""
Test that thinking_blocks on assistant messages are converted to content
blocks prepended before the existing content.
"""
config = HostedVLLMChatConfig()
messages = [
{
"role": "user",
"content": "Hello",
},
{
"role": "assistant",
"content": "Here is my answer.",
"thinking_blocks": [
{
"type": "thinking",
"thinking": "Let me reason about this...",
"signature": "abc123",
}
],
},
{
"role": "user",
"content": "Follow up question",
},
]
transformed = config.transform_request(
model="hosted_vllm/llama-3.1-70b-instruct",
messages=messages,
optional_params={},
litellm_params={},
headers={},
)
assistant_msg = transformed["messages"][1]
assert assistant_msg["role"] == "assistant"
assert isinstance(assistant_msg["content"], list)
assert assistant_msg["content"][0] == {
"type": "thinking",
"thinking": "Let me reason about this...",
}
assert assistant_msg["content"][1] == {
"type": "text",
"text": "Here is my answer.",
}
assert "thinking_blocks" not in assistant_msg
def test_hosted_vllm_thinking_blocks_with_list_content():
"""
Test thinking_blocks prepended when assistant content is already a list.
"""
config = HostedVLLMChatConfig()
messages = [
{
"role": "assistant",
"content": [{"type": "text", "text": "Response text"}],
"thinking_blocks": [
{
"type": "thinking",
"thinking": "Step 1 reasoning",
"signature": "sig1",
},
{
"type": "thinking",
"thinking": "Step 2 reasoning",
"signature": "sig2",
},
],
},
]
transformed = config.transform_request(
model="hosted_vllm/llama-3.1-70b-instruct",
messages=messages,
optional_params={},
litellm_params={},
headers={},
)
assistant_msg = transformed["messages"][0]
assert len(assistant_msg["content"]) == 3
assert assistant_msg["content"][0] == {
"type": "thinking",
"thinking": "Step 1 reasoning",
}
assert assistant_msg["content"][1] == {
"type": "thinking",
"thinking": "Step 2 reasoning",
}
assert assistant_msg["content"][2] == {"type": "text", "text": "Response text"}
assert "thinking_blocks" not in assistant_msg