From 52d086d46abfbc1eb8b83676136a67f7fb61c491 Mon Sep 17 00:00:00 2001 From: Alexander Minges Date: Fri, 20 Feb 2026 18:08:04 +0100 Subject: [PATCH] revert: restore context.py and manager.py to tanishra baseline (out of scope) --- nanobot/agent/context.py | 7 +-- nanobot/channels/manager.py | 88 +++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/nanobot/agent/context.py b/nanobot/agent/context.py index 0253415..876d43d 100644 --- a/nanobot/agent/context.py +++ b/nanobot/agent/context.py @@ -102,11 +102,8 @@ Your workspace is at: {workspace_path} - Custom skills: {workspace_path}/skills/{{skill-name}}/SKILL.md IMPORTANT: When responding to direct questions or conversations, reply directly with your text response. -Use the 'message' tool only when you need explicit channel delivery behavior: -- Send to a different channel/chat than the current session -- Send one or more file attachments via `media` (local file paths) -For normal conversation text, respond directly without calling the message tool. -Do not claim that attachments are impossible if a channel supports file send and you can provide local paths. +Only use the 'message' tool when you need to send a message to a specific chat channel (like WhatsApp). +For normal conversation, just respond with text - do not call the message tool. Always be helpful, accurate, and concise. Before calling tools, briefly tell the user what you're about to do (one short sentence in the user's language). When remembering something important, write to {workspace_path}/memory/MEMORY.md diff --git a/nanobot/channels/manager.py b/nanobot/channels/manager.py index 998d90c..e860d26 100644 --- a/nanobot/channels/manager.py +++ b/nanobot/channels/manager.py @@ -16,29 +16,28 @@ from nanobot.config.schema import Config class ChannelManager: """ Manages chat channels and coordinates message routing. - + Responsibilities: - Initialize enabled channels (Telegram, WhatsApp, etc.) - Start/stop channels - Route outbound messages """ - + def __init__(self, config: Config, bus: MessageBus): self.config = config self.bus = bus self.channels: dict[str, BaseChannel] = {} self._dispatch_task: asyncio.Task | None = None - + self._init_channels() - + def _init_channels(self) -> None: """Initialize channels based on config.""" - + # Telegram channel if self.config.channels.telegram.enabled: try: from nanobot.channels.telegram import TelegramChannel - self.channels["telegram"] = TelegramChannel( self.config.channels.telegram, self.bus, @@ -47,13 +46,14 @@ class ChannelManager: logger.info("Telegram channel enabled") except ImportError as e: logger.warning(f"Telegram channel not available: {e}") - + # WhatsApp channel if self.config.channels.whatsapp.enabled: try: from nanobot.channels.whatsapp import WhatsAppChannel - - self.channels["whatsapp"] = WhatsAppChannel(self.config.channels.whatsapp, self.bus) + self.channels["whatsapp"] = WhatsAppChannel( + self.config.channels.whatsapp, self.bus + ) logger.info("WhatsApp channel enabled") except ImportError as e: logger.warning(f"WhatsApp channel not available: {e}") @@ -62,18 +62,20 @@ class ChannelManager: if self.config.channels.discord.enabled: try: from nanobot.channels.discord import DiscordChannel - - self.channels["discord"] = DiscordChannel(self.config.channels.discord, self.bus) + self.channels["discord"] = DiscordChannel( + self.config.channels.discord, self.bus + ) logger.info("Discord channel enabled") except ImportError as e: logger.warning(f"Discord channel not available: {e}") - + # Feishu channel if self.config.channels.feishu.enabled: try: from nanobot.channels.feishu import FeishuChannel - - self.channels["feishu"] = FeishuChannel(self.config.channels.feishu, self.bus) + self.channels["feishu"] = FeishuChannel( + self.config.channels.feishu, self.bus + ) logger.info("Feishu channel enabled") except ImportError as e: logger.warning(f"Feishu channel not available: {e}") @@ -83,7 +85,9 @@ class ChannelManager: try: from nanobot.channels.mochat import MochatChannel - self.channels["mochat"] = MochatChannel(self.config.channels.mochat, self.bus) + self.channels["mochat"] = MochatChannel( + self.config.channels.mochat, self.bus + ) logger.info("Mochat channel enabled") except ImportError as e: logger.warning(f"Mochat channel not available: {e}") @@ -92,8 +96,9 @@ class ChannelManager: if self.config.channels.dingtalk.enabled: try: from nanobot.channels.dingtalk import DingTalkChannel - - self.channels["dingtalk"] = DingTalkChannel(self.config.channels.dingtalk, self.bus) + self.channels["dingtalk"] = DingTalkChannel( + self.config.channels.dingtalk, self.bus + ) logger.info("DingTalk channel enabled") except ImportError as e: logger.warning(f"DingTalk channel not available: {e}") @@ -102,8 +107,9 @@ class ChannelManager: if self.config.channels.email.enabled: try: from nanobot.channels.email import EmailChannel - - self.channels["email"] = EmailChannel(self.config.channels.email, self.bus) + self.channels["email"] = EmailChannel( + self.config.channels.email, self.bus + ) logger.info("Email channel enabled") except ImportError as e: logger.warning(f"Email channel not available: {e}") @@ -112,8 +118,9 @@ class ChannelManager: if self.config.channels.slack.enabled: try: from nanobot.channels.slack import SlackChannel - - self.channels["slack"] = SlackChannel(self.config.channels.slack, self.bus) + self.channels["slack"] = SlackChannel( + self.config.channels.slack, self.bus + ) logger.info("Slack channel enabled") except ImportError as e: logger.warning(f"Slack channel not available: {e}") @@ -122,7 +129,6 @@ class ChannelManager: if self.config.channels.qq.enabled: try: from nanobot.channels.qq import QQChannel - self.channels["qq"] = QQChannel( self.config.channels.qq, self.bus, @@ -130,7 +136,7 @@ class ChannelManager: logger.info("QQ channel enabled") except ImportError as e: logger.warning(f"QQ channel not available: {e}") - + async def _start_channel(self, name: str, channel: BaseChannel) -> None: """Start a channel and log any exceptions.""" try: @@ -143,23 +149,23 @@ class ChannelManager: if not self.channels: logger.warning("No channels enabled") return - + # Start outbound dispatcher self._dispatch_task = asyncio.create_task(self._dispatch_outbound()) - + # Start channels tasks = [] for name, channel in self.channels.items(): logger.info(f"Starting {name} channel...") tasks.append(asyncio.create_task(self._start_channel(name, channel))) - + # Wait for all to complete (they should run forever) await asyncio.gather(*tasks, return_exceptions=True) - + async def stop_all(self) -> None: """Stop all channels and the dispatcher.""" logger.info("Stopping all channels...") - + # Stop dispatcher if self._dispatch_task: self._dispatch_task.cancel() @@ -167,7 +173,7 @@ class ChannelManager: await self._dispatch_task except asyncio.CancelledError: pass - + # Stop all channels for name, channel in self.channels.items(): try: @@ -175,15 +181,18 @@ class ChannelManager: logger.info(f"Stopped {name} channel") except Exception as e: logger.error(f"Error stopping {name}: {e}") - + async def _dispatch_outbound(self) -> None: """Dispatch outbound messages to the appropriate channel.""" logger.info("Outbound dispatcher started") - + while True: try: - msg = await asyncio.wait_for(self.bus.consume_outbound(), timeout=1.0) - + msg = await asyncio.wait_for( + self.bus.consume_outbound(), + timeout=1.0 + ) + channel = self.channels.get(msg.channel) if channel: try: @@ -192,23 +201,26 @@ class ChannelManager: logger.error(f"Error sending to {msg.channel}: {e}") else: logger.warning(f"Unknown channel: {msg.channel}") - + except asyncio.TimeoutError: continue except asyncio.CancelledError: break - + def get_channel(self, name: str) -> BaseChannel | None: """Get a channel by name.""" return self.channels.get(name) - + def get_status(self) -> dict[str, Any]: """Get status of all channels.""" return { - name: {"enabled": True, "running": channel.is_running} + name: { + "enabled": True, + "running": channel.is_running + } for name, channel in self.channels.items() } - + @property def enabled_channels(self) -> list[str]: """Get list of enabled channel names."""