From 188e6df757e9fbb478ca141c406d2e23e1fea7b7 Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Fri, 1 May 2026 12:04:03 +0000 Subject: [PATCH] fix(utils): cover complete trailing think markers Made-with: Cursor --- nanobot/utils/helpers.py | 4 ++-- tests/agent/test_runner.py | 21 +++++++++++++++++++++ tests/utils/test_strip_think.py | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/nanobot/utils/helpers.py b/nanobot/utils/helpers.py index 3ce15ad6..ae008bec 100644 --- a/nanobot/utils/helpers.py +++ b/nanobot/utils/helpers.py @@ -63,8 +63,8 @@ def strip_think(text: str) -> str: # Stream chunks may end in the middle of a control tag. Strip only known # control-token prefixes at the very end. partial_control_tag = ( - r"?" + r"|<\|?(?:c|ch|cha|chan|chann|channe|channel)(?:\|?>?)?" ) text = re.sub(rf"(?:{partial_control_tag})$", "", text) text = re.sub(r"^\s*<\|?$", "", text) diff --git a/tests/agent/test_runner.py b/tests/agent/test_runner.py index 79af0a67..10d25348 100644 --- a/tests/agent/test_runner.py +++ b/tests/agent/test_runner.py @@ -993,6 +993,27 @@ async def test_loop_stream_filter_hides_partial_trailing_think_prefix(tmp_path): assert deltas == ["Hello", " World"] +@pytest.mark.asyncio +async def test_loop_stream_filter_hides_complete_trailing_think_tag(tmp_path): + loop = _make_loop(tmp_path) + deltas: list[str] = [] + + async def chat_stream_with_retry(*, on_content_delta, **kwargs): + await on_content_delta("Hello ") + await on_content_delta("hiddenWorld") + return LLMResponse(content="Hello hiddenWorld", tool_calls=[], usage={}) + + loop.provider.chat_stream_with_retry = chat_stream_with_retry + + async def on_stream(delta: str) -> None: + deltas.append(delta) + + final_content, _, _, _, _ = await loop._run_agent_loop([], on_stream=on_stream) + + assert final_content == "Hello World" + assert deltas == ["Hello", " World"] + + @pytest.mark.asyncio async def test_loop_retries_think_only_final_response(tmp_path): loop = _make_loop(tmp_path) diff --git a/tests/utils/test_strip_think.py b/tests/utils/test_strip_think.py index 7adbe7bc..5db93e65 100644 --- a/tests/utils/test_strip_think.py +++ b/tests/utils/test_strip_think.py @@ -105,10 +105,12 @@ class TestStripThinkMalformedLeaks: def test_partial_trailing_think_tag_after_visible_text(self): assert strip_think("喷泉策略说明 ") == "answer" def test_partial_trailing_channel_marker_after_visible_text(self): assert strip_think("喷泉策略说明 <|chan") == "喷泉策略说明" assert strip_think("answer ") == "answer" class TestStripThinkConservativePreserve: