Mattermost slash command handling and registration improvements

NousResearch/hermes-agent · cluster 6296 · gateway

Data as of

3 open items. Fix merged in #59127. Check it covers your case.

The short answer

2open issues
1open PR
11items grouped
Known?
Yes. 11 related items grouped here, 3 issues already closed.
Fix event
A fix was merged to main in PR #59127. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this partially resolved, deciding PR #59127. That is separate from the fix event.
Still open
2 issues and 1 PR.

These issues and pull requests address problems with Mattermost slash command parsing (leading whitespace, escaping, mobile compatibility) and add features such as registering commands with autocomplete and interactive approval buttons.

Open issues2

  • Issue#6296[Feature]: Mattermost adapter should register COMMAND_REGISTRY as custom slash commands with autocomplete
  • Issue#27587[Feature]: Mattermost: Add interactive button-based approval for dangerous commands

Open PRs1

  • PR#29373feat(mattermost): add interactive approval buttons via send_exec_approval

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #59127 fix(mattermost): accept leading-space slash commands

    merged to main

    files: plugins/platforms/mattermost/adapter.py, scripts/release.py, tests/gateway/test_mattermost.py

    Show the diff
    • plugins/platforms/mattermost/adapter.py
      @@ -878,6 +878,8 @@ async def _handle_ws_event(self, event: Dict[str, Any]) -> None:
               # Determine message type.
               file_ids = post.get("file_ids") or []
               msg_type = MessageType.TEXT
      +        if message_text[:1].isspace() and message_text.lstrip().startswith("/"):
      +            message_text = message_text.lstrip()
               if message_text.startswith("/"):
                   msg_type = MessageType.COMMAND
       
    • scripts/release.py
      @@ -45,6 +45,7 @@
       
       # Auto-extracted from noreply emails + manual overrides
       AUTHOR_MAP = {
      +    "[redacted:email]": "l0h1nth",  # PR #32210 salvage (mattermost: accept leading-space slash commands from mobile clients; #25184)
           "[redacted:email]": "devatnull",  # PR #58704 salvage (whatsapp: native Baileys polls, clarify-as-poll, location pins, structured quoted replies, PTT/audio split, bridge_helpers extraction)
           "[redacted:email]": "tjp2021",  # PR #4097 salvage (copilot: per-turn x-initiator header so user prompts bill as premium requests; #3040)
           "[redacted:email]": "kevinrajaram",  # PR #3850 salvage (gateway: add POSIX system dirs to PATH so launchctl/systemctl resolve under UV's minimal-PATH bundled Python; #3849)
    • tests/gateway/test_mattermost.py
      @@ -6,6 +6,7 @@
       from unittest.mock import MagicMock, patch, AsyncMock
       
       from gateway.config import Platform, PlatformConfig
      +from gateway.platforms.base import MessageType
       from gateway.run import (
           _resolve_gateway_display_bool,
           _resolve_progress_thread_id,
      @@ -588,6 +589,55 @@ async def test_channel_type_mapping(self):
               msg_event = self.adapter.handle_message.call_args[0][0]
               assert msg_event.source.chat_type == "dm"
       
      +    @pytest.mark.asyncio
      +    async def test_leading_space_slash_command_is_command(self):
      +        """Mattermost mobile suggests leading-space slash commands."""
      +        post_data = {
      +            "id": "post_cmd",
      +            "user_id": "user_123",
      +            "channel_id": "chan_dm",
      +            "message": " /new",
      +        }
      +        event = {
      +            "event": "posted",
      +            "data": {
      +                "post": json.dumps(post_data),
      +                "channel_type": "D",
      +                "sender_name": "@bob",
      +            },
      +        }
      +
      +        await self.adapter._handle_ws_event(event)
      +        assert self.adapter.handle_message.called
      +        msg_event = self.adapter.handle_message.call_args[0][0]
      +        assert msg_event.text == "/new"
      +        assert msg_event.message_type is MessageType.COMMAND
      +        assert msg_event.get_command() == "new"
      +
      +    @pytest.mark.asyncio
      +    async def test_leading_space_normal_text_is_preserved(self):
      +        """Only command-shaped mobile messages should be normalized."""
      +        post_data = {
      +            "id": "post_text",
      +            "user_id": "user_123",
      +            "channel_id": "chan_dm",
      +            "message": " hello",
      +        }
      +        event = {
      +            "event": "posted",
      +            "data": {
      +                "post": json.dumps(post_data),
      +                "channel_type": "D",
      +                "sender_name": "@bob",
      +            },
      +        }
      +
      +        await self.adapter._handle_ws_event(event)
      +        assert self.adapter.handle_message.called
      +        msg_event = self.adapter.handle_message.call_args[0][0]
      +        assert msg_event.text == " hello"
      +        assert msg_event.message_type is MessageType.TEXT
      +
           @pytest.mark.asyncio
           async def test_thread_id_from_root_id(self):
               """Post with root_id should have thread_id set."""

4 PRs closed without merging

From the close comments: merged via another change 2 · done elsewhere 1 · stale or abandoned 1

  • #6298 feat(gateway/mattermost): register COMMAND_REGISTRY as custom slash commands · stale or abandoned
  • #21070 fix(gateway): handle Mattermost escaped slash commands · done elsewhere → #59127, #32210
  • #25187 fix(gateway): Mattermost Thread and Command Handling Fixes · merged via another change → 06161c6, 1197d2b, #59127, #20874
  • #32210 fix(mattermost): accept leading-space slash commands · merged via another change → #59127, #21070
Closed issues · 3
  • Closed#20649[Feature]: Do `lstrip` user command is used to support MatterMost.
  • Closed#25184[Bug]: Mattermost mobile users are unable to send commands.
  • Closed#59535Mattermost: /approve interrupted by leading whitespace from autocomplete (incomplete fix from #46866)
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.15: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
gateway
Merged PRs
#59127
Closed issues
3
Attempts
4 PRs closed without merging
Fix link checked
5 Jul 2026

For your agent

The same facts, typed.