/ in Telegram or Discord shows a native menu of every bot command with its description.
CommandRegistry is the single source of truth. Adapters project it into each platform’s native menu at startup — no extra code, and every register_command-added command shows up too.
What Appears in the Menu
Both built-in and custom commands surface in the/ menu, filtered per user by CommandAccessPolicy.
| Built-in commands | Custom commands |
|---|---|
/status, /new, /help, /stop, /model | Any command added with register_command(name, handler, description=...) |
/usage, /compress, /queue, /undo | The description you pass becomes the menu label |
/sessions, /resume, /retry, /reasoning | Restrict to platforms with channels=[...] |
/whoami, /sethome, /learn | Hidden from a user’s menu when the policy denies it |
user_allowed_commands allows.
Platform Support
| Platform | Native menu | How |
|---|---|---|
| Telegram | ✅ | bot.set_my_commands(BotCommand(...)) at startup |
| Discord | ✅ | Application commands on CommandTree, sync() on on_ready |
| Slack | ⚠️ | Base no-op — commands still work by typing, no native menu yet |
| ⚠️ | Base no-op — WhatsApp has no / command menu API |
Quick Start
Start a Telegram bot — built-ins appear automatically
Every built-in command shows up in
/ autocomplete with no extra code.Register a custom command — it joins the menu
Pass a
description — it becomes the label users see in the menu.How It Works
At startup each adapter builds policy-filtered(name, description) pairs from the registry, then publishes them to the platform’s native menu.
| Step | Method | Where |
|---|---|---|
| Build entries | build_command_menu_entries(user_id) | ChatCommandMixin |
| Resolve truth | registry.menu_entries(platform, policy, user_id, extra_commands) | CommandRegistry |
| Publish | publish_command_menu(entries) | Adapter override |
Access-Control Interaction
CommandAccessPolicy filters menu_entries() per user — admins see everything, regular users only see commands in their user_allowed_commands.
Command Access Control
admin_users, user_allowed_commands, and /whoami
Custom Commands API
Custom commands use the sameregister_command() API documented in Bot Chat Commands.
Any command registered via
register_command(..., description=...) appears in the native / menu automatically. Descriptions ARE the menu labels — write them for humans.Best Practices
Always pass a description
Always pass a description
The
description becomes the native menu label. A command with no description shows a generic placeholder.Restrict privileged commands with CommandAccessPolicy
Restrict privileged commands with CommandAccessPolicy
Filtered menus keep the UX safe — a user never sees a command they cannot run. See Command Access Control.
Use channels for platform-specific commands
Use channels for platform-specific commands
Pass
channels=["telegram"] when a command only makes sense on one platform — it’s hidden from other platforms’ menus.Related
Bot Chat Commands
Built-in and custom commands
Command Access Control
admin_users, user_allowed_commands, /whoami
Gateway
Gateway and control-plane overview
Learn a Skill
The privileged /learn command

