[RL][TITO] Preserve whitespace in reasoning parser outputs (#24251)
This commit is contained in:
@@ -1228,6 +1228,37 @@ class ServingChatTestCase(unittest.TestCase):
|
||||
req.reasoning_effort = effort
|
||||
self.assertEqual(chat._get_reasoning_from_request(req), expected)
|
||||
|
||||
def test_non_stream_reasoning_response_preserves_payload_whitespace(self):
|
||||
self.chat.reasoning_parser = "qwen3"
|
||||
self.template_manager.force_reasoning = False
|
||||
|
||||
req = ChatCompletionRequest(
|
||||
model="x",
|
||||
messages=[{"role": "user", "content": "Hi?"}],
|
||||
stream=False,
|
||||
separate_reasoning=True,
|
||||
)
|
||||
ret = [
|
||||
{
|
||||
"text": "<think>\nLet me think\n</think>\n\nThe answer is 42.\n",
|
||||
"meta_info": {
|
||||
"id": "chatcmpl-test",
|
||||
"prompt_tokens": 5,
|
||||
"completion_tokens": 8,
|
||||
"cached_tokens": 0,
|
||||
"finish_reason": {"type": "stop", "matched": None},
|
||||
"weight_version": "test",
|
||||
},
|
||||
"index": 0,
|
||||
}
|
||||
]
|
||||
|
||||
response = self.chat._build_chat_response(req, ret, created=123)
|
||||
|
||||
message = response.choices[0].message
|
||||
self.assertEqual(message.reasoning_content, "\nLet me think\n")
|
||||
self.assertEqual(message.content, "\n\nThe answer is 42.\n")
|
||||
|
||||
# ------------- reasoning config tests -------------
|
||||
def test_get_reasoning_from_request_default_true_toggle(self):
|
||||
self.tm.server_args.reasoning_parser = "qwen3"
|
||||
|
||||
@@ -861,6 +861,37 @@ class TestReasoningParser(CustomTestCase):
|
||||
self.assertEqual(reasoning, "Let me think")
|
||||
self.assertEqual(normal, "The answer is 42.")
|
||||
|
||||
def test_parse_non_stream_preserves_payload_whitespace(self):
|
||||
"""Non-streaming parsing must not rewrite text inside or after reasoning."""
|
||||
parser = ReasoningParser("qwen3")
|
||||
reasoning, normal = parser.parse_non_stream(
|
||||
"<think>\nLet me think\n</think>\n\nThe answer is 42.\n"
|
||||
)
|
||||
self.assertEqual(reasoning, "\nLet me think\n")
|
||||
self.assertEqual(normal, "\n\nThe answer is 42.\n")
|
||||
|
||||
def test_parse_non_stream_strips_repeated_leading_start_tokens(self):
|
||||
"""Repeated leading start tokens are markers, not reasoning payload."""
|
||||
parser = ReasoningParser("qwen3")
|
||||
reasoning, normal = parser.parse_non_stream(
|
||||
"<think><think>Let me think</think>The answer is 42."
|
||||
)
|
||||
self.assertEqual(reasoning, "Let me think")
|
||||
self.assertEqual(normal, "The answer is 42.")
|
||||
|
||||
def test_parse_stream_chunk_preserves_payload_whitespace(self):
|
||||
"""Streaming parsing preserves the same generated payload whitespace."""
|
||||
parser = ReasoningParser("qwen3")
|
||||
reasoning, normal = parser.parse_stream_chunk("<think>")
|
||||
self.assertEqual(reasoning, "")
|
||||
self.assertEqual(normal, "")
|
||||
|
||||
reasoning, normal = parser.parse_stream_chunk(
|
||||
"\nLet me think\n</think>\n\nThe answer is 42.\n"
|
||||
)
|
||||
self.assertEqual(reasoning, "\nLet me think\n")
|
||||
self.assertEqual(normal, "\n\nThe answer is 42.\n")
|
||||
|
||||
def test_parse_stream_chunk(self):
|
||||
"""Test streaming chunk parsing."""
|
||||
parser = ReasoningParser("qwen3")
|
||||
|
||||
Reference in New Issue
Block a user