From 0d4af68e63a26a3a077179f287bb555c66ad119c Mon Sep 17 00:00:00 2001 From: chengyongru Date: Wed, 17 Jun 2026 18:16:56 +0800 Subject: [PATCH] fix: silence unroutable cli progress noise --- nanobot/channels/manager.py | 2 +- nanobot/command/builtin.py | 4 +++ tests/command/test_builtin_dream.py | 41 ++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/nanobot/channels/manager.py b/nanobot/channels/manager.py index a28ebdcb..6504d1ab 100644 --- a/nanobot/channels/manager.py +++ b/nanobot/channels/manager.py @@ -171,7 +171,7 @@ class ChannelManager: """Return whether progress (or tool-hints) may be sent to *channel_name*.""" ch = self.channels.get(channel_name) if ch is None: - logger.warning("Progress check for unknown channel: {}", channel_name) + logger.debug("Progress check for unknown channel: {}", channel_name) return False return ch.send_tool_hints if tool_hint else ch.send_progress diff --git a/nanobot/command/builtin.py b/nanobot/command/builtin.py index d94fc4db..4a34f894 100644 --- a/nanobot/command/builtin.py +++ b/nanobot/command/builtin.py @@ -311,6 +311,9 @@ async def cmd_dream(ctx: CommandContext) -> OutboundMessage: msg = ctx.msg async def _run_dream(): + async def _silent(*_args, **_kwargs): + pass + from nanobot.agent.memory import MemoryStore dream_session_key = MemoryStore.dream_session_key @@ -337,6 +340,7 @@ async def cmd_dream(ctx: CommandContext) -> OutboundMessage: session_key=key, ephemeral=True, tools=store.build_dream_tools(), + on_progress=_silent, ) elapsed = time.monotonic() - t0 if MemoryStore.dream_run_completed(resp): diff --git a/tests/command/test_builtin_dream.py b/tests/command/test_builtin_dream.py index 1a15055d..660969c4 100644 --- a/tests/command/test_builtin_dream.py +++ b/tests/command/test_builtin_dream.py @@ -5,7 +5,7 @@ from types import SimpleNamespace import pytest -from nanobot.bus.events import InboundMessage +from nanobot.bus.events import InboundMessage, OutboundMessage from nanobot.command.builtin import cmd_dream, cmd_dream_log, cmd_dream_restore from nanobot.command.router import CommandContext from nanobot.utils.gitstore import CommitInfo @@ -24,6 +24,12 @@ class _FakeStore: def build_dream_prompt(self): return self._dream_prompt_result + def build_dream_tools(self): + return None + + def set_last_dream_cursor(self, value: int) -> None: + self._last_dream_cursor = value + def compact_history(self) -> None: self.compact_history_called = True @@ -105,6 +111,39 @@ async def test_dream_no_history_explains_how_to_create_input(tmp_path) -> None: assert "agents.defaults.idleCompactAfterMinutes" in content +@pytest.mark.asyncio +async def test_dream_internal_run_silences_progress(tmp_path) -> None: + msg = InboundMessage(channel="feishu", sender_id="u1", chat_id="chat1", content="/dream") + store = _FakeStore(_FakeGit(initialized=False), dream_prompt_result=("dream prompt", 123)) + bus = _FakeBus() + calls = [] + + async def process_direct(*args, **kwargs): + calls.append((args, kwargs)) + return OutboundMessage( + channel="cli", + chat_id="direct", + content="done", + metadata={"_stop_reason": "completed"}, + ) + + sessions_dir = tmp_path / "sessions" + sessions_dir.mkdir() + loop = SimpleNamespace( + bus=bus, + context=SimpleNamespace(memory=store, timezone="UTC"), + sessions=SimpleNamespace(sessions_dir=sessions_dir), + process_direct=process_direct, + ) + ctx = CommandContext(msg=msg, session=None, key=msg.session_key, raw="/dream", args="", loop=loop) + + await cmd_dream(ctx) + await asyncio.sleep(0) + + assert len(calls) == 1 + assert callable(calls[0][1]["on_progress"]) + + @pytest.mark.asyncio async def test_dream_log_latest_is_more_user_friendly() -> None: commit = CommitInfo(sha="abcd1234", message="dream: 2026-04-04, 2 change(s)", timestamp="2026-04-04 12:00")