From 1c5eadc23b90c43e2eb170ec5b842628beee0a02 Mon Sep 17 00:00:00 2001 From: agentson Date: Thu, 5 Feb 2026 15:52:35 +0900 Subject: [PATCH] fix: remove /start command and handle @botname suffix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove /start command as name doesn't match functionality, and fix command parsing to handle @botname suffix for group chat compatibility. Changes: - Remove handle_start function and registration - Remove /start from help command list - Remove test_start_command_content test - Strip @botname suffix from commands (e.g., /help@mybot → help) Rationale: - /start command name implies bot initialization, but it was just showing help text (duplicate of /help) - Better to have one clear /help command - @botname suffix handling needed for group chats Test: - 27 tests pass (1 removed, 1 added for @botname handling) - All existing functionality preserved Co-Authored-By: Claude Sonnet 4.5 --- src/main.py | 16 ------- src/notifications/telegram_client.py | 3 +- tests/test_telegram_commands.py | 72 ++++++++++------------------ 3 files changed, 27 insertions(+), 64 deletions(-) diff --git a/src/main.py b/src/main.py index e372a5e..7257188 100644 --- a/src/main.py +++ b/src/main.py @@ -579,25 +579,10 @@ async def run(settings: Settings) -> None: command_handler = TelegramCommandHandler(telegram) # Register basic commands - async def handle_start() -> None: - """Handle /start command.""" - message = ( - "🤖 The Ouroboros Trading Bot\n\n" - "AI-powered global stock trading agent with real-time notifications.\n\n" - "Available commands:\n" - "/help - Show this help message\n" - "/status - Current trading status\n" - "/positions - View holdings\n" - "/stop - Pause trading\n" - "/resume - Resume trading" - ) - await telegram.send_message(message) - async def handle_help() -> None: """Handle /help command.""" message = ( "📖 Available Commands\n\n" - "/start - Welcome message\n" "/help - Show available commands\n" "/status - Trading status (mode, markets, P&L)\n" "/positions - Current holdings\n" @@ -722,7 +707,6 @@ async def run(settings: Settings) -> None: "⚠️ Error\n\nFailed to retrieve positions." ) - command_handler.register_command("start", handle_start) command_handler.register_command("help", handle_help) command_handler.register_command("stop", handle_stop) command_handler.register_command("resume", handle_resume) diff --git a/src/notifications/telegram_client.py b/src/notifications/telegram_client.py index 4765cb4..3482646 100644 --- a/src/notifications/telegram_client.py +++ b/src/notifications/telegram_client.py @@ -492,7 +492,8 @@ class TelegramCommandHandler: if not command_parts: return - command_name = command_parts[0] + # Remove @botname suffix if present (for group chats) + command_name = command_parts[0].split("@")[0] # Execute handler handler = self._commands.get(command_name) diff --git a/tests/test_telegram_commands.py b/tests/test_telegram_commands.py index 3438005..1b78a6e 100644 --- a/tests/test_telegram_commands.py +++ b/tests/test_telegram_commands.py @@ -230,6 +230,31 @@ class TestUpdateHandling: await handler._handle_update(update) assert executed is False + @pytest.mark.asyncio + async def test_handle_command_with_botname(self) -> None: + """Commands with @botname suffix are handled correctly.""" + client = TelegramClient(bot_token="123:abc", chat_id="456", enabled=True) + handler = TelegramCommandHandler(client) + + executed = False + + async def test_command() -> None: + nonlocal executed + executed = True + + handler.register_command("start", test_command) + + update = { + "update_id": 1, + "message": { + "chat": {"id": 456}, + "text": "/start@mybot", + }, + } + + await handler._handle_update(update) + assert executed is True + @pytest.mark.asyncio async def test_handle_update_error_isolation(self) -> None: """Errors in handlers don't crash the system.""" @@ -638,51 +663,6 @@ class TestStatusCommands: class TestBasicCommands: """Test basic command implementations.""" - @pytest.mark.asyncio - async def test_start_command_content(self) -> None: - """Start command contains welcome message and command list.""" - client = TelegramClient(bot_token="123:abc", chat_id="456", enabled=True) - handler = TelegramCommandHandler(client) - - mock_resp = AsyncMock() - mock_resp.status = 200 - mock_resp.__aenter__ = AsyncMock(return_value=mock_resp) - mock_resp.__aexit__ = AsyncMock(return_value=False) - - async def mock_start() -> None: - """Mock /start handler.""" - message = ( - "🤖 The Ouroboros Trading Bot\n\n" - "AI-powered global stock trading agent with real-time notifications.\n\n" - "Available commands:\n" - "/help - Show this help message\n" - "/status - Current trading status\n" - "/positions - View holdings\n" - "/stop - Pause trading\n" - "/resume - Resume trading" - ) - await client.send_message(message) - - handler.register_command("start", mock_start) - - with patch("aiohttp.ClientSession.post", return_value=mock_resp) as mock_post: - update = { - "update_id": 1, - "message": { - "chat": {"id": 456}, - "text": "/start", - }, - } - - await handler._handle_update(update) - - # Verify message was sent - assert mock_post.call_count == 1 - payload = mock_post.call_args.kwargs["json"] - assert "Ouroboros Trading Bot" in payload["text"] - assert "/help" in payload["text"] - assert "/status" in payload["text"] - @pytest.mark.asyncio async def test_help_command_content(self) -> None: """Help command lists all available commands.""" @@ -698,7 +678,6 @@ class TestBasicCommands: """Mock /help handler.""" message = ( "📖 Available Commands\n\n" - "/start - Welcome message\n" "/help - Show available commands\n" "/status - Trading status (mode, markets, P&L)\n" "/positions - Current holdings\n" @@ -724,7 +703,6 @@ class TestBasicCommands: assert mock_post.call_count == 1 payload = mock_post.call_args.kwargs["json"] assert "Available Commands" in payload["text"] - assert "/start" in payload["text"] assert "/help" in payload["text"] assert "/status" in payload["text"] assert "/positions" in payload["text"]