Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions gateway/platforms/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class _MockContextTypes:
}


MAX_COMMANDS_PER_SCOPE = 30
MAX_COMMANDS_PER_SCOPE = 100


def check_telegram_requirements() -> bool:
Expand Down Expand Up @@ -2209,9 +2209,8 @@ def _polling_error_callback(error: Exception) -> None:
BotCommandScopeDefault,
)
from hermes_cli.commands import telegram_menu_commands
# Telegram allows up to 100 commands but has an undocumented
# payload size limit (~4KB total). Limit to 30 core commands
# to stay well under the threshold while covering all categories.
# Telegram allows up to 100 commands via setMyCommands.
# Register all discovered commands (core + plugin + skill).
menu_commands, hidden_count = telegram_menu_commands(max_commands=MAX_COMMANDS_PER_SCOPE)
bot_commands = [BotCommand(name, desc) for name, desc in menu_commands]
# Register for all scopes independently β€” Telegram picks the
Expand All @@ -2231,7 +2230,7 @@ def _polling_error_callback(error: Exception) -> None:
if hidden_count:
logger.info(
"[%s] Telegram menu: %d commands registered, %d hidden (over %d limit). Use /commands for full list.",
self.name, len(menu_commands), hidden_count, 30,
self.name, len(menu_commands), hidden_count, MAX_COMMANDS_PER_SCOPE,
)
except Exception as e:
logger.warning(
Expand Down
32 changes: 32 additions & 0 deletions tests/hermes_cli/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,38 @@ def test_operational_builtins_survive_thirty_command_cap(self, tmp_path, monkeyp
):
assert name in names


def test_plugin_commands_survive_hundred_command_cap(self, tmp_path, monkeypatch):
"""Regression test for #33480: plugin commands must appear in Telegram menu.

With MAX_COMMANDS_PER_SCOPE raised from 30 to 100, plugin commands
should no longer be truncated by the built-in command priority.
"""
from unittest.mock import patch
import hermes_cli.plugins as plugins_mod

plugin_dir = tmp_path / "plugins" / "test-plugin"
plugin_dir.mkdir(parents=True, exist_ok=True)
(plugin_dir / "plugin.yaml").write_text(
"name: test-plugin\nversion: 0.1.0\ndescription: Test plugin\n"
)
(plugin_dir / "__init__.py").write_text(
"def register(ctx):\n"
" ctx.register_command('my_plugin_cmd', lambda args: 'ok', description='Plugin test command')\n"
)
(tmp_path / "config.yaml").write_text(
"plugins:\n enabled:\n - test-plugin\n"
)
monkeypatch.setenv("HERMES_HOME", str(tmp_path))

with patch.object(plugins_mod, "_plugin_manager", None):
menu, _ = telegram_menu_commands(max_commands=100)

menu_names = {name for name, _ in menu}
assert "my_plugin_cmd" in menu_names, (
"Plugin command 'my_plugin_cmd' should appear in Telegram menu "
"with 100-command cap (#33480 regression)"
)
def test_includes_plugin_commands_via_lazy_discovery(self, tmp_path, monkeypatch):
"""Telegram menu generation should discover plugin slash commands on first access."""
from unittest.mock import patch
Expand Down
Loading