Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions tests/entrypoints/openai/responses/test_harmony_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from vllm.entrypoints.openai.responses.harmony import (
harmony_to_response_output,
parser_state_to_response_output,
response_input_to_harmony,
response_previous_input_to_harmony,
)

Expand Down Expand Up @@ -461,3 +462,83 @@ def test_parser_state_to_response_output_analysis_channel() -> None:
assert len(builtin_items) == 1
assert not isinstance(builtin_items[0], McpCall)
assert builtin_items[0].type == "reasoning"


class TestResponseInputToHarmonyReasoning:
"""Tests for response_input_to_harmony with reasoning type inputs."""

def test_reasoning_with_content(self):
"""Test reasoning item with populated content field."""
reasoning_msg = ResponseReasoningItem(
id="rs_001",
type="reasoning",
summary=[],
content=[{"type": "reasoning_content", "text": "thinking step"}],
encrypted_content=None,
)

msg = response_input_to_harmony(reasoning_msg, [])

assert msg.role == Role.ASSISTANT
assert msg.content[0].text == "thinking step"

def test_reasoning_with_content_none_and_summary(self):
"""Test reasoning item with content=None falls back to summary."""
reasoning_msg = ResponseReasoningItem(
id="rs_002",
type="reasoning",
summary=[{"type": "summary_text", "text": "We need to check the file"}],
content=None,
encrypted_content=None,
)

msg = response_input_to_harmony(reasoning_msg, [])

assert msg.role == Role.ASSISTANT
assert msg.content[0].text == "We need to check the file"

def test_reasoning_with_content_none_and_multiple_summaries(self):
"""Test reasoning item with content=None and multiple summary entries."""
reasoning_msg = ResponseReasoningItem(
id="rs_003",
type="reasoning",
summary=[
{"type": "summary_text", "text": "First thought."},
{"type": "summary_text", "text": "Second thought."},
],
content=None,
encrypted_content=None,
)

msg = response_input_to_harmony(reasoning_msg, [])

assert msg.role == Role.ASSISTANT
assert msg.content[0].text == "First thought. Second thought."

def test_reasoning_with_content_none_and_empty_summary(self):
"""Test reasoning item with content=None and empty summary list."""
reasoning_msg = ResponseReasoningItem(
id="rs_004",
type="reasoning",
summary=[],
content=None,
encrypted_content=None,
)

msg = response_input_to_harmony(reasoning_msg, [])

assert msg.role == Role.ASSISTANT
assert msg.content[0].text == ""

def test_reasoning_with_content_none_and_no_summary(self):
"""Test reasoning item with both content and summary absent."""
reasoning_msg = {
"id": "rs_005",
"type": "reasoning",
"content": None,
}

msg = response_input_to_harmony(reasoning_msg, [])

assert msg.role == Role.ASSISTANT
assert msg.content[0].text == ""
16 changes: 13 additions & 3 deletions vllm/entrypoints/openai/responses/harmony.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,19 @@
response_msg["output"],
)
elif response_msg["type"] == "reasoning":
content = response_msg["content"]
assert len(content) == 1
msg = Message.from_role_and_content(Role.ASSISTANT, content[0]["text"])
content = response_msg.get("content")
if content is not None:
assert len(content) == 1
text = content[0]["text"]
else:
# content can be None when encrypted_content is used or
# when only summary is available. Fall back to summary.
summary = response_msg.get("summary")
if summary:
text = " ".join(s.get("text", "") for s in summary)
else:
text = ""

Check failure on line 186 in vllm/entrypoints/openai/responses/harmony.py

View workflow job for this annotation

GitHub Actions / pre-commit

Ruff (SIM108)

vllm/entrypoints/openai/responses/harmony.py:183:13: SIM108 Use ternary operator `text = " ".join(s.get("text", "") for s in summary) if summary else ""` instead of `if`-`else`-block
msg = Message.from_role_and_content(Role.ASSISTANT, text)
elif response_msg["type"] == "function_call":
msg = Message.from_role_and_content(Role.ASSISTANT, response_msg["arguments"])
msg = msg.with_channel("commentary")
Expand Down
Loading