Skip to content

feat: implement register_command() on plugin context#10626

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-ed6ef586
Apr 16, 2026
Merged

feat: implement register_command() on plugin context#10626
teknium1 merged 1 commit into
mainfrom
hermes/hermes-ed6ef586

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Completes the half-built plugin slash command system. The dispatch code in cli.py and gateway/run.py already called get_plugin_command_handler() but the registration API on PluginContext was never implemented — plugins had no way to register slash commands.

What this enables

Plugins can now register in-session slash commands (e.g. /lcm, /lossless) during their register(ctx) call:

def register(ctx):
    ctx.register_command(
        "lcm",
        handler=lambda raw_args: handle_lcm_command(raw_args, engine),
        description="LCM status and diagnostics",
    )

These are distinct from register_cli_command() which creates hermes <subcommand> terminal commands — register_command() creates slash commands available inside CLI and gateway conversations.

Changes

hermes_cli/plugins.py (core):

  • register_command(name, handler, description) on PluginContext — normalizes names, rejects conflicts with built-in commands
  • _plugin_commands dict on PluginManager
  • commands_registered tracking on LoadedPlugin
  • get_plugin_command_handler(name) and get_plugin_commands() module-level functions

hermes_cli/commands.py (integration):

  • Telegram bot menu now uses actual plugin command description (was hardcoded "Plugin command")
  • SlashCommandCompleter now includes plugin commands in autocomplete

cli.py (display):

  • /plugins command now shows command count alongside tools/hooks

Existing dispatch (already wired, no changes needed)

  • cli.py:5566 — dispatches to get_plugin_command_handler()
  • gateway/run.py:3140 — dispatches with async handler support
  • commands.py:448 — includes plugin commands in gateway menus

Test plan

  • 12 new tests in TestPluginCommands: registration, normalization, conflict detection, handler dispatch, introspection, full discover_and_load() integration
  • All 149 plugin + command tests pass

Closes #10495

Complete the half-built plugin slash command system. The dispatch
code in cli.py and gateway/run.py already called
get_plugin_command_handler() but the registration side was never
implemented.

Changes:
- Add register_command() to PluginContext — stores handler,
  description, and plugin name; normalizes names; rejects conflicts
  with built-in commands
- Add _plugin_commands dict to PluginManager
- Add commands_registered tracking on LoadedPlugin
- Add get_plugin_command_handler() and get_plugin_commands()
  module-level convenience functions
- Fix commands.py to use actual plugin description in Telegram
  bot menu (was hardcoded 'Plugin command')
- Add plugin commands to SlashCommandCompleter autocomplete
- Show command count in /plugins display
- 12 new tests covering registration, conflict detection,
  normalization, handler dispatch, and introspection

Closes #10495
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

⚠️ WARNING: Dependency manifest files modified

Changes to dependency files can introduce new packages or change version pins. Verify all dependency changes are intentional and from trusted sources.

Files:

pyproject.toml

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@teknium1 teknium1 merged commit 498b995 into main Apr 16, 2026
6 of 7 checks passed
@teknium1 teknium1 deleted the hermes/hermes-ed6ef586 branch April 16, 2026 02:53
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
)

Complete the half-built plugin slash command system. The dispatch
code in cli.py and gateway/run.py already called
get_plugin_command_handler() but the registration side was never
implemented.

Changes:
- Add register_command() to PluginContext — stores handler,
  description, and plugin name; normalizes names; rejects conflicts
  with built-in commands
- Add _plugin_commands dict to PluginManager
- Add commands_registered tracking on LoadedPlugin
- Add get_plugin_command_handler() and get_plugin_commands()
  module-level convenience functions
- Fix commands.py to use actual plugin description in Telegram
  bot menu (was hardcoded 'Plugin command')
- Add plugin commands to SlashCommandCompleter autocomplete
- Show command count in /plugins display
- 12 new tests covering registration, conflict detection,
  normalization, handler dispatch, and introspection

Closes NousResearch#10495
aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
)

Complete the half-built plugin slash command system. The dispatch
code in cli.py and gateway/run.py already called
get_plugin_command_handler() but the registration side was never
implemented.

Changes:
- Add register_command() to PluginContext — stores handler,
  description, and plugin name; normalizes names; rejects conflicts
  with built-in commands
- Add _plugin_commands dict to PluginManager
- Add commands_registered tracking on LoadedPlugin
- Add get_plugin_command_handler() and get_plugin_commands()
  module-level convenience functions
- Fix commands.py to use actual plugin description in Telegram
  bot menu (was hardcoded 'Plugin command')
- Add plugin commands to SlashCommandCompleter autocomplete
- Show command count in /plugins display
- 12 new tests covering registration, conflict detection,
  normalization, handler dispatch, and introspection

Closes NousResearch#10495
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
)

Complete the half-built plugin slash command system. The dispatch
code in cli.py and gateway/run.py already called
get_plugin_command_handler() but the registration side was never
implemented.

Changes:
- Add register_command() to PluginContext — stores handler,
  description, and plugin name; normalizes names; rejects conflicts
  with built-in commands
- Add _plugin_commands dict to PluginManager
- Add commands_registered tracking on LoadedPlugin
- Add get_plugin_command_handler() and get_plugin_commands()
  module-level convenience functions
- Fix commands.py to use actual plugin description in Telegram
  bot menu (was hardcoded 'Plugin command')
- Add plugin commands to SlashCommandCompleter autocomplete
- Show command count in /plugins display
- 12 new tests covering registration, conflict detection,
  normalization, handler dispatch, and introspection

Closes NousResearch#10495
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
)

Complete the half-built plugin slash command system. The dispatch
code in cli.py and gateway/run.py already called
get_plugin_command_handler() but the registration side was never
implemented.

Changes:
- Add register_command() to PluginContext — stores handler,
  description, and plugin name; normalizes names; rejects conflicts
  with built-in commands
- Add _plugin_commands dict to PluginManager
- Add commands_registered tracking on LoadedPlugin
- Add get_plugin_command_handler() and get_plugin_commands()
  module-level convenience functions
- Fix commands.py to use actual plugin description in Telegram
  bot menu (was hardcoded 'Plugin command')
- Add plugin commands to SlashCommandCompleter autocomplete
- Show command count in /plugins display
- 12 new tests covering registration, conflict detection,
  normalization, handler dispatch, and introspection

Closes NousResearch#10495
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
)

Complete the half-built plugin slash command system. The dispatch
code in cli.py and gateway/run.py already called
get_plugin_command_handler() but the registration side was never
implemented.

Changes:
- Add register_command() to PluginContext — stores handler,
  description, and plugin name; normalizes names; rejects conflicts
  with built-in commands
- Add _plugin_commands dict to PluginManager
- Add commands_registered tracking on LoadedPlugin
- Add get_plugin_command_handler() and get_plugin_commands()
  module-level convenience functions
- Fix commands.py to use actual plugin description in Telegram
  bot menu (was hardcoded 'Plugin command')
- Add plugin commands to SlashCommandCompleter autocomplete
- Show command count in /plugins display
- 12 new tests covering registration, conflict detection,
  normalization, handler dispatch, and introspection

Closes NousResearch#10495
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: implement register_command() on plugin context

1 participant