fix(gateway): hide required-arg commands from Telegram menu

This commit is contained in:
MrBob 2026-05-03 16:49:37 -03:00 committed by Teknium
parent 408dd8aa28
commit 86e64c1d3b
3 changed files with 34 additions and 2 deletions

View file

@ -399,6 +399,11 @@ def _is_gateway_available(cmd: CommandDef, config_overrides: set[str] | None = N
return False
def _requires_argument(args_hint: str) -> bool:
"""Return True when selecting a command without text would be incomplete."""
return args_hint.strip().startswith("<")
def gateway_help_lines() -> list[str]:
"""Generate gateway help text lines from the registry."""
overrides = _resolve_config_gates()
@ -455,7 +460,9 @@ def telegram_bot_commands() -> list[tuple[str, str]]:
Telegram command names cannot contain hyphens, so they are replaced with
underscores. Aliases are skipped -- Telegram shows one menu entry per
canonical command.
canonical command. Commands that require arguments are skipped because
selecting a Telegram BotCommand sends only ``/command`` and would execute
an incomplete command.
Plugin-registered slash commands are included so plugins get native
autocomplete in Telegram without touching core code.
@ -465,10 +472,14 @@ def telegram_bot_commands() -> list[tuple[str, str]]:
for cmd in COMMAND_REGISTRY:
if not _is_gateway_available(cmd, overrides):
continue
if _requires_argument(cmd.args_hint):
continue
tg_name = _sanitize_telegram_name(cmd.name)
if tg_name:
result.append((tg_name, cmd.description))
for name, description, _args_hint in _iter_plugin_command_entries():
for name, description, args_hint in _iter_plugin_command_entries():
if _requires_argument(args_hint):
continue
tg_name = _sanitize_telegram_name(name)
if tg_name:
result.append((tg_name, description))

View file

@ -623,6 +623,7 @@ AUTHOR_MAP = {
"cine.dreamer.one@gmail.com": "LeonSGP43",
"zyprothh@gmail.com": "Zyproth",
"amitgaur@gmail.com": "amitgaur",
"albuquerque.abner@gmail.com": "mrbob-git",
"leozeli@qq.com": "leozeli",
"linlehao@cuhk.edu.cn": "LehaoLin",
"liutong@isacas.ac.cn": "I3eg1nner",

View file

@ -236,6 +236,13 @@ class TestTelegramBotCommands:
tg_name = cmd.name.replace("-", "_")
assert tg_name not in names
def test_excludes_commands_with_required_args(self):
names = {name for name, _ in telegram_bot_commands()}
assert "background" not in names
assert "queue" not in names
assert "steer" not in names
assert "background" in GATEWAY_KNOWN_COMMANDS
class TestSlackSubcommandMap:
def test_returns_dict(self):
@ -1661,6 +1668,19 @@ class TestPluginCommandEnumeration:
names = {name for name, _desc in telegram_bot_commands()}
assert "metricas" in names
def test_plugin_command_with_required_args_excluded_from_telegram_menu(self, monkeypatch):
"""Telegram BotCommand selections cannot supply required arguments."""
self._patch_plugin_commands(monkeypatch, {
"background-job": {
"handler": lambda _a: "ok",
"description": "Run a background job",
"args_hint": "<prompt>",
"plugin": "jobs-plugin",
}
})
names = {name for name, _desc in telegram_bot_commands()}
assert "background_job" not in names
def test_plugin_command_appears_in_slack_subcommand_map(self, monkeypatch):
"""/hermes metricas must route through the Slack subcommand map."""
self._patch_plugin_commands(monkeypatch, {