diff --git a/nanobot/agent/runner.py b/nanobot/agent/runner.py index 8bb81ef8..d124156f 100644 --- a/nanobot/agent/runner.py +++ b/nanobot/agent/runner.py @@ -771,18 +771,24 @@ class AgentRunner: await live_file_edits.update(delta) if wants_streaming: + thinking_buf = "" + async def _stream(delta: str) -> None: if delta: context.streamed_content = True await hook.on_stream(context, delta) async def _thinking(delta: str) -> None: + nonlocal thinking_buf if not delta: return - delta = strip_reasoning_tags(delta) - if delta: + prev_clean = strip_reasoning_tags(thinking_buf) + thinking_buf += delta + new_clean = strip_reasoning_tags(thinking_buf) + incremental = new_clean[len(prev_clean):] + if incremental: context.streamed_reasoning = True - await hook.emit_reasoning(delta) + await hook.emit_reasoning(incremental) async def _stream_recover() -> None: await hook.on_stream_end(context, resuming=True) diff --git a/nanobot/utils/helpers.py b/nanobot/utils/helpers.py index 99863c33..c545e9ca 100644 --- a/nanobot/utils/helpers.py +++ b/nanobot/utils/helpers.py @@ -134,10 +134,15 @@ def strip_reasoning_tags(text: object) -> str: """Remove wrapper tags from text that is already known to be reasoning.""" if not isinstance(text, str): return "" + partial_reasoning_tag = ( + r"?" + ) + text = re.sub(rf"^\s*(?:{partial_reasoning_tag})$", "", text) text = re.sub(r"^\s*<(?:think|thinking|thought)/>\s*", "", text) text = re.sub(r"\s*<(?:think|thinking|thought)/>\s*$", "", text) text = re.sub(r"^\s*<(?:think|thinking|thought)>\s*", "", text) text = re.sub(r"\s*\s*$", "", text) + text = re.sub(rf"\s*(?:{partial_reasoning_tag})$", "", text) return text.strip() diff --git a/tests/agent/test_runner_reasoning.py b/tests/agent/test_runner_reasoning.py index af71008c..2dbd46d1 100644 --- a/tests/agent/test_runner_reasoning.py +++ b/tests/agent/test_runner_reasoning.py @@ -381,8 +381,8 @@ async def test_runner_strips_thinking_tags_from_native_thinking_deltas(): *, on_content_delta=None, on_thinking_delta=None, **kwargs ): if on_thinking_delta: - await on_thinking_delta("") - await on_thinking_delta("Preparing final response") + await on_thinking_delta("Preparing final response") await on_thinking_delta("") if on_content_delta: await on_content_delta("done")