# NousResearch/hermes-agent · edit_message missing finalize kwarg across platform adapters

## Open now

- Nothing open on GitHub.

Multiple platform adapters (WhatsApp, Telegram, Discord, Slack, Matrix, Mattermost) do not accept a 'finalize' keyword argument in their edit_message implementations. Issues and fixes address adding this missing parameter consistently across all adapters.

## TL;DR

- 6 member(s): 0 open issue(s), 3 closed issue(s), 0 open PR(s), 1 merged PR(s), 2 PR(s) closed without merging.
- A fix was merged to main in PR #12854. Verify it addresses your case.
- **Recommended:** read PR #12854 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `partially_resolved` · deciding PR(s): `pr-12854`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_PARTIAL`): 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.27`: the share of member 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.

## Closed / duplicate issues

- #12290: fix(mattermost): edit_message rejects finalize kwarg after DingTalk AI Cards merge
- #12579: edit_message missing finalize parameter in Telegram/Discord/Slack/Matrix adapters
- #12925: WhatsApp streaming broken in v0.10.0: edit_message() rejects 'finalize' kwarg

## Prior & competing PRs

- **#12854: fix(gateway): accept finalize kwarg in all platform edit_message overrides**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `gateway/platforms/discord.py`, `gateway/platforms/feishu.py`, `gateway/platforms/matrix.py`, `gateway/platforms/mattermost.py`, `gateway/platforms/slack.py`, `gateway/platforms/telegram.py`, `gateway/platforms/whatsapp.py`, `scripts/release.py`, `tests/gateway/test_stream_consumer.py`
  - fix hunks:
  - `gateway/platforms/discord.py`

    ```diff
    @@ -1081,6 +1081,8 @@ async def edit_message(
             chat_id: str,
             message_id: str,
             content: str,
    +        *,
    +        finalize: bool = False,
         ) -> SendResult:
             """Edit a previously sent Discord message."""
             if not self._client:
    ```
  - `gateway/platforms/feishu.py`

    ```diff
    @@ -1468,6 +1468,8 @@ async def edit_message(
             chat_id: str,
             message_id: str,
             content: str,
    +        *,
    +        finalize: bool = False,
         ) -> SendResult:
             """Edit a previously sent Feishu text/post message."""
             if not self._client:
    ```
  - `gateway/platforms/matrix.py`

    ```diff
    @@ -825,7 +825,7 @@ async def stop_typing(self, chat_id: str) -> None:
     
     
         async def edit_message(
    -        self, chat_id: str, message_id: str, content: str
    +        self, chat_id: str, message_id: str, content: str, *, finalize: bool = False
         ) -> SendResult:
             """Edit an existing message (via m.replace)."""
     
    ```
  - `gateway/platforms/mattermost.py`

    ```diff
    @@ -304,7 +304,7 @@ async def send_typing(
             )
     
         async def edit_message(
    -        self, chat_id: str, message_id: str, content: str
    +        self, chat_id: str, message_id: str, content: str, *, finalize: bool = False
         ) -> SendResult:
             """Edit an existing post."""
             formatted = self.format_message(content)
    ```
  - `gateway/platforms/slack.py`

    ```diff
    @@ -316,6 +316,8 @@ async def edit_message(
             chat_id: str,
             message_id: str,
             content: str,
    +        *,
    +        finalize: bool = False,
         ) -> SendResult:
             """Edit a previously sent Slack message."""
             if not self._app:
    ```
  - `gateway/platforms/telegram.py`

    ```diff
    @@ -1081,6 +1081,8 @@ async def edit_message(
             chat_id: str,
             message_id: str,
             content: str,
    +        *,
    +        finalize: bool = False,
         ) -> SendResult:
             """Edit a previously sent Telegram message."""
             if not self._bot:
    ```
  - `gateway/platforms/whatsapp.py`

    ```diff
    @@ -655,6 +655,8 @@ async def edit_message(
             chat_id: str,
             message_id: str,
             content: str,
    +        *,
    +        finalize: bool = False,
         ) -> SendResult:
             """Edit a previously sent message via the WhatsApp bridge."""
             if not self._running or not self._http_session:
    ```
  - `scripts/release.py`

    ```diff
    @@ -219,6 +219,7 @@
         "[redacted:email]": "iacker",
         "[redacted:email]": "sontianye",
         "[redacted:email]": "jackjin1997",
    +    "[redacted:email]": "jackjin1997",
         "[redacted:email]": "danieldoderlein",
         "[redacted:email]": "lrawnsley",
         "[redacted:email]": "taeuk178",
    ```
  - `tests/gateway/test_stream_consumer.py`

    ```diff
    @@ -133,6 +133,43 @@ async def test_identical_text_skip_respects_adapter_flag(self):
             assert picky.edit_message.call_args[1]["finalize"] is True
     
     
    +class TestEditMessageFinalizeSignature:
    +    """Every concrete platform adapter must accept the ``finalize`` kwarg.
    +
    +    stream_consumer._send_or_edit always passes ``finalize=`` to
    +    ``adapter.edit_message(...)`` (see gateway/stream_consumer.py).  An
    +    adapter that overrides edit_message without accepting finalize raises
    +    TypeError the first time streaming hits a segment break or final edit.
    +    Guard the contract with an explicit signature check so it cannot
    +    silently regress — existing tests use MagicMock which swallows any
    +    kwarg and cannot catch this.
    +    """
    +
    +    @pytest.mark.parametrize(
    +        "module_path,class_name",
    +        [
    +            ("gateway.platforms.telegram", "TelegramAdapter"),
    +            ("gateway.platforms.discord", "DiscordAdapter"),
    +            ("gateway.platforms.slack", "SlackAdapter"),
    +            ("gateway.platforms.matrix", "MatrixAdapter"),
    +            ("gateway.platforms.mattermost", "MattermostAdapter"),
    +            ("gateway.platforms.feishu", "FeishuAdapter"),
    +            ("gateway.platforms.whatsapp", "WhatsAppAdapter"),
    +            ("gateway.platforms.dingtalk", "DingTalkAdapter"),
    +        ],
    +    )
    +    def test_edit_message_accepts_finalize(self, module_path, class_name):
    +        import inspect
    +
    +        module = pytest.importorskip(module_path)
    +        cls = getattr(module, class_name)
    +        params = inspect.signature(cls.edit_message).parameters
    +        assert "finalize" in params, (
    +            f"{class_name}.edit_message must accept 'finalize' kwarg; "
    +            f"stream_consumer._send_or_edit passes it unconditionally"
    +        )
    +
    +
     class TestSendOrEditMediaStripping:
         """Verify _send_or_edit strips MEDIA: before sending to the platform."""
     
    ```
- **#12601: fix(gateway): accept finalize kwarg in all platform edit_message overrides**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `#12854`
- **#12828: fix(gateway): add missing finalize parameter to edit_message in all platform adapters**. closed without merge
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#12854`, `#12601`

## Fix status

- Merged to main in PR #12854 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-04-20`. This confirmation is old and may be out of date (a revert/reopen would not have invalidated it here); re-verify.
- Subsystem: `gateway`
