From 22120ef00ff3941c423179ab5f26d28a08ccf15e Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 18 May 2026 23:55:03 -0700 Subject: [PATCH] Revert "feat(telegram): support quick-command-only menus" This reverts commit b1acf80e17858e2e5ae7c0d412a3a573d7fcbca4. --- gateway/config.py | 2 +- gateway/platforms/telegram.py | 21 ++---------- hermes_cli/commands.py | 36 -------------------- tests/gateway/test_config.py | 19 ----------- tests/hermes_cli/test_commands.py | 42 ------------------------ website/docs/reference/slash-commands.md | 5 --- website/docs/user-guide/configuration.md | 22 ------------- 7 files changed, 3 insertions(+), 144 deletions(-) diff --git a/gateway/config.py b/gateway/config.py index 589debc5890..56401763a1e 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -1074,7 +1074,7 @@ def load_gateway_config() -> GatewayConfig: if isinstance(group_allowed_chats, list): group_allowed_chats = ",".join(str(v) for v in group_allowed_chats) os.environ["TELEGRAM_GROUP_ALLOWED_CHATS"] = str(group_allowed_chats) - for _telegram_extra_key in ("guest_mode", "disable_link_previews", "command_menu"): + for _telegram_extra_key in ("guest_mode", "disable_link_previews"): if _telegram_extra_key in telegram_cfg: plat_data = platforms_data.setdefault(Platform.TELEGRAM.value, {}) if not isinstance(plat_data, dict): diff --git a/gateway/platforms/telegram.py b/gateway/platforms/telegram.py index e715b018df3..cba396741fb 100644 --- a/gateway/platforms/telegram.py +++ b/gateway/platforms/telegram.py @@ -1527,28 +1527,11 @@ class TelegramAdapter(BasePlatformAdapter): BotCommandScopeDefault, BotCommandScopeChat, ) - from hermes_cli.commands import ( - telegram_menu_commands, - telegram_quick_menu_commands, - ) + 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. - if self.config.extra.get("command_menu") == "quick_commands_only": - # Fetch quick_commands via the gateway runner reference if - # available; otherwise fall back to PlatformConfig.extra. - _qc = self.config.extra.get("quick_commands") - if not isinstance(_qc, dict) or not _qc: - _runner_ref = getattr(self, "_runner_ref", None) - _runner = _runner_ref() if callable(_runner_ref) else None - _gw_cfg = getattr(_runner, "config", None) if _runner else None - _qc = getattr(_gw_cfg, "quick_commands", {}) or {} - menu_commands, hidden_count = telegram_quick_menu_commands( - _qc, - max_commands=MAX_COMMANDS_PER_SCOPE, - ) - else: - menu_commands, hidden_count = telegram_menu_commands(max_commands=MAX_COMMANDS_PER_SCOPE) + 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 # narrowest matching scope per chat type (forum topics fall diff --git a/hermes_cli/commands.py b/hermes_cli/commands.py index 610621aed6f..9fc0472f512 100644 --- a/hermes_cli/commands.py +++ b/hermes_cli/commands.py @@ -740,42 +740,6 @@ def telegram_menu_commands(max_commands: int = 100) -> tuple[list[tuple[str, str return all_commands[:max_commands], hidden_count -def telegram_quick_menu_commands( - quick_commands: Mapping[str, Any] | None, - max_commands: int = 100, -) -> tuple[list[tuple[str, str]], int]: - """Return Telegram BotCommands for profile-defined quick commands only. - - Specialist Telegram bots often use ``quick_commands`` as their whole - user-facing interface. This helper lets a profile opt into a focused - Telegram slash menu without exposing every generic Hermes command. - - ``show_in_telegram_menu: false`` hides a quick command from the native - menu while leaving gateway dispatch unchanged. - """ - if not isinstance(quick_commands, Mapping): - return [], 0 - - menu: list[tuple[str, str]] = [] - seen: set[str] = set() - for raw_name, raw_config in quick_commands.items(): - if not isinstance(raw_name, str) or not isinstance(raw_config, Mapping): - continue - if raw_config.get("show_in_telegram_menu") is False: - continue - name = _sanitize_telegram_name(raw_name) - if not name or name in seen: - continue - desc = str(raw_config.get("description") or f"Run /{raw_name}") - if len(desc) > 40: - desc = desc[:37] + "..." - menu.append((name, desc)) - seen.add(name) - - hidden_count = max(0, len(menu) - max_commands) - return menu[:max_commands], hidden_count - - def discord_skill_commands( max_slots: int, reserved_names: set[str], diff --git a/tests/gateway/test_config.py b/tests/gateway/test_config.py index ea00a44b1d6..da7673011fe 100644 --- a/tests/gateway/test_config.py +++ b/tests/gateway/test_config.py @@ -270,25 +270,6 @@ class TestLoadGatewayConfig: assert config.quick_commands == {"limits": {"type": "exec", "command": "echo ok"}} - def test_bridges_telegram_command_menu_from_config_yaml(self, tmp_path, monkeypatch): - hermes_home = tmp_path / ".hermes" - hermes_home.mkdir() - config_path = hermes_home / "config.yaml" - config_path.write_text( - "telegram:\n" - " command_menu: quick_commands_only\n", - encoding="utf-8", - ) - - monkeypatch.setenv("HERMES_HOME", str(hermes_home)) - - config = load_gateway_config() - - assert ( - config.platforms[Platform.TELEGRAM].extra["command_menu"] - == "quick_commands_only" - ) - def test_bridges_group_sessions_per_user_from_config_yaml(self, tmp_path, monkeypatch): hermes_home = tmp_path / ".hermes" hermes_home.mkdir() diff --git a/tests/hermes_cli/test_commands.py b/tests/hermes_cli/test_commands.py index 7fefd7470c7..6de778347e1 100644 --- a/tests/hermes_cli/test_commands.py +++ b/tests/hermes_cli/test_commands.py @@ -26,7 +26,6 @@ from hermes_cli.commands import ( slack_subcommand_map, telegram_bot_commands, telegram_menu_commands, - telegram_quick_menu_commands, ) @@ -1154,47 +1153,6 @@ class TestTelegramMenuCommands: # No empty string in menu names assert "" not in menu_names - def test_quick_menu_commands_include_profile_quick_commands_only(self): - menu, hidden = telegram_quick_menu_commands( - { - "agent-health": { - "type": "exec", - "command": "echo ok", - "description": "Show agent health", - }, - "hidden": { - "type": "exec", - "command": "echo hidden", - "description": "Hidden command", - "show_in_telegram_menu": False, - }, - } - ) - - assert hidden == 0 - assert menu == [("agent_health", "Show agent health")] - - def test_quick_menu_commands_sanitize_dedupe_and_trim_descriptions(self): - menu, hidden = telegram_quick_menu_commands( - { - "agent-health": { - "description": "A" * 80, - }, - "agent_health": { - "description": "Duplicate after sanitization", - }, - "+++": { - "description": "Sanitizes to empty", - }, - }, - max_commands=1, - ) - - assert hidden == 0 - assert len(menu) == 1 - assert menu[0][0] == "agent_health" - assert menu[0][1] == ("A" * 37) + "..." - # --------------------------------------------------------------------------- # Backward-compat aliases diff --git a/website/docs/reference/slash-commands.md b/website/docs/reference/slash-commands.md index 249db462b8b..d545c8242bd 100644 --- a/website/docs/reference/slash-commands.md +++ b/website/docs/reference/slash-commands.md @@ -143,11 +143,6 @@ quick_commands: Then type `/status`, `/deploy`, or `/inbox` in the CLI or a messaging platform. Quick commands are resolved at dispatch time and may not appear in every built-in autocomplete/help table. -For specialist Telegram bots, set `telegram.command_menu: quick_commands_only` -to make Telegram's native slash menu show only profile-defined quick commands. -Set `show_in_telegram_menu: false` on a quick command to keep it callable but -hide it from the Telegram menu. - String-only prompt shortcuts are not supported as quick commands. Put longer reusable prompts in a skill, or use `type: alias` to point at an existing slash command. ### Custom model aliases diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index ba1a64c20a5..40f924aa209 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -1433,28 +1433,6 @@ Usage: type `/status`, `/disk`, `/update`, `/gpu`, or `/restart` in the CLI or a - **Type** — supported types are `exec` and `alias`; other types show an error - **Works everywhere** — CLI, Telegram, Discord, Slack, WhatsApp, Signal, Email, Home Assistant -Telegram profiles can opt into a focused BotCommand menu that shows only -profile-defined quick commands: - -```yaml -telegram: - command_menu: quick_commands_only - -quick_commands: - health: - type: exec - command: scripts/health.sh - description: Show service health - internal-debug: - type: exec - command: scripts/debug.sh - description: Internal debug helper - show_in_telegram_menu: false -``` - -`show_in_telegram_menu: false` hides a quick command from Telegram's native -slash menu while leaving the command callable. - String-only prompt shortcuts are not valid quick commands. For reusable prompt workflows, create a skill or alias to an existing slash command. ## Human Delay