Fix dropped Inkling reasoning at stream end (#31787)
This commit is contained in:
@@ -782,6 +782,20 @@ class InklingDetector(BaseReasoningFormatDetector):
|
|||||||
self._buffer = ""
|
self._buffer = ""
|
||||||
return self._parse_blocks(text)
|
return self._parse_blocks(text)
|
||||||
|
|
||||||
|
def finish(self) -> StreamingParseResult:
|
||||||
|
# Flush reasoning buffered under stream_reasoning=False when the stream
|
||||||
|
# ends before a control/end token closes the block (e.g. max_tokens cut
|
||||||
|
# a thinking block short). Mirrors the non-streaming flush in
|
||||||
|
# detect_and_parse; without it the trailing reasoning trace is dropped.
|
||||||
|
reasoning_text = ""
|
||||||
|
if self._kind == "reasoning" and not self.stream_reasoning:
|
||||||
|
reasoning_text = self._pending_reasoning
|
||||||
|
self._buffer = ""
|
||||||
|
self._pending_reasoning = ""
|
||||||
|
self._pending_header = ""
|
||||||
|
self._kind = None
|
||||||
|
return StreamingParseResult(reasoning_text=reasoning_text)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _partial_control_length(text: str) -> int:
|
def _partial_control_length(text: str) -> int:
|
||||||
max_token_len = max(map(len, _INKLING_CONTROL_TOKENS))
|
max_token_len = max(map(len, _INKLING_CONTROL_TOKENS))
|
||||||
|
|||||||
@@ -249,6 +249,24 @@ class TestInklingDetector(CustomTestCase):
|
|||||||
content += detector.parse_streaming_increment(chunk).normal_text
|
content += detector.parse_streaming_increment(chunk).normal_text
|
||||||
self.assertEqual(content, " worldnext", msg=f"chunks={chunks!r}")
|
self.assertEqual(content, " worldnext", msg=f"chunks={chunks!r}")
|
||||||
|
|
||||||
|
def test_finish_flushes_reasoning_truncated_before_end_token(self):
|
||||||
|
"""Bug regression: with stream_reasoning=False the detector buffers the
|
||||||
|
thinking block and only flushes it on a control/end token. When
|
||||||
|
generation is cut mid-block (e.g. max_tokens) the stream ends with no
|
||||||
|
end token, so the buffered trace was dropped entirely; finish() must
|
||||||
|
emit it, matching the non-streaming detect_and_parse path."""
|
||||||
|
detector = InklingDetector(stream_reasoning=False)
|
||||||
|
source = "<|message_model|><|content_thinking|>truncated thinking"
|
||||||
|
streamed_reasoning = ""
|
||||||
|
for char in source:
|
||||||
|
streamed_reasoning += detector.parse_streaming_increment(
|
||||||
|
char
|
||||||
|
).reasoning_text
|
||||||
|
# The block never closed, so nothing surfaces mid-stream.
|
||||||
|
self.assertEqual(streamed_reasoning, "")
|
||||||
|
# finish() flushes the buffered trace instead of dropping it.
|
||||||
|
self.assertEqual(detector.finish().reasoning_text, "truncated thinking")
|
||||||
|
|
||||||
|
|
||||||
class TestKimiDetector(CustomTestCase):
|
class TestKimiDetector(CustomTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user