What
_handle_command (bot.py:640) dispatches on exact string equality against the raw message text (e.g. if command == "/model":). A command sent with trailing arguments (/model gpt-4) or a bot-username suffix — which Telegram clients add automatically in group chats (/start@blacki_bot) — matches no branch. There is no else clause, no fallback message, and no log line, so the command is silently dropped with zero feedback to the user.
The entry point is bot.py:495 (if user_message.startswith("/"): await self._handle_command(message, user_message)), which passes the full raw text straight through.
Why it matters
This is very likely to happen in practice: Telegram groups append @botname to slash commands by default, and any future command that's designed to take an argument (none currently do, but /model, for example, could plausibly grow one) would hit this immediately. Users get no indication anything went wrong.
Priority
Medium — affects real usage in group chats today (any /start, /help, /reset, /model, /thinking, or health command typed in a group will include the @botname suffix and silently fail), not just a hypothetical future case.
Level of Effort
Small (S) — add a _parse_command(text) -> str helper that strips a @botname suffix and any trailing arguments before the if/elif dispatch, mirroring the normalization the settings-callback parser already does. No dispatch-table restructuring needed.
Sources
Passing criteria / definition of done
- A new test sends
"/start@blacki_bot" in a group chat and asserts _send_start_message (or equivalent) is still invoked.
- A new test sends
"/model gpt-4" and asserts _settings_menu.send_model_menu is still invoked (trailing arguments are stripped, not required to be understood).
- A new test confirms a genuinely unrecognized command (not just a suffix/argument variant) still results in no dispatch (i.e. the fix doesn't make the parser overly permissive).
pytest tests/test_telegram_bot.py -q passes with the new assertions.
ruff check, ruff format --check, and mypy src/blacki/telegram/ all pass with no new warnings.
What
_handle_command(bot.py:640) dispatches on exact string equality against the raw message text (e.g.if command == "/model":). A command sent with trailing arguments (/model gpt-4) or a bot-username suffix — which Telegram clients add automatically in group chats (/start@blacki_bot) — matches no branch. There is noelseclause, no fallback message, and no log line, so the command is silently dropped with zero feedback to the user.The entry point is bot.py:495 (
if user_message.startswith("/"): await self._handle_command(message, user_message)), which passes the full raw text straight through.Why it matters
This is very likely to happen in practice: Telegram groups append
@botnameto slash commands by default, and any future command that's designed to take an argument (none currently do, but/model, for example, could plausibly grow one) would hit this immediately. Users get no indication anything went wrong.Priority
Medium — affects real usage in group chats today (any
/start,/help,/reset,/model,/thinking, or health command typed in a group will include the@botnamesuffix and silently fail), not just a hypothetical future case.Level of Effort
Small (S) — add a
_parse_command(text) -> strhelper that strips a@botnamesuffix and any trailing arguments before theif/elifdispatch, mirroring the normalization the settings-callback parser already does. No dispatch-table restructuring needed.Sources
telegram/bot.py_handle_commandtelegram/bot.py_handle_update(call site)tests/test_telegram_bot.py(existing coverage to extend)Passing criteria / definition of done
"/start@blacki_bot"in a group chat and asserts_send_start_message(or equivalent) is still invoked."/model gpt-4"and asserts_settings_menu.send_model_menuis still invoked (trailing arguments are stripped, not required to be understood).pytest tests/test_telegram_bot.py -qpasses with the new assertions.ruff check,ruff format --check, andmypy src/blacki/telegram/all pass with no new warnings.