mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
Second migration of an existing built-in platform adapter after Discord (PR #30591) — follows the same shape established by IRC / Teams / LINE / Google Chat / SimpleX and the playbook in `references/platform-plugin-migration.md`. Advances the umbrella refactor in #3823. Matches Discord's parity bar — adapter under `plugins/platforms/mattermost/` with the standard `__init__.py` / `adapter.py` / `plugin.yaml` shell, `register(ctx)` entry point, **no back-compat shim** at the old import path, and full parity for all five hooks Discord uses plus the `apply_yaml_config_fn` hook (mattermost is the second consumer of #25443 after Discord): * `standalone_sender_fn` — out-of-process cron delivery via Mattermost REST API. Picks up the thread_id + media_files capabilities the legacy `_send_mattermost` lacked (parity with Discord's `_standalone_send`). * `setup_fn` — interactive `hermes setup gateway` wizard. * `apply_yaml_config_fn` — translates `config.yaml` `mattermost:` keys (`require_mention`, `free_response_channels`, `allowed_channels`) into `MATTERMOST_*` env vars (replaces the hardcoded block in `gateway/config.py`). * `is_connected` — declares connection state from `MATTERMOST_TOKEN` + `MATTERMOST_URL`. * `check_fn` — verifies aiohttp is installed and both required env vars are set. * plus `allowed_users_env`, `allow_all_env`, `cron_deliver_env_var`, `max_message_length` (4000 — Mattermost practical limit), `emoji`, `required_env`, `install_hint`. Files ----- * `gateway/platforms/mattermost.py` (873 LOC) → `plugins/platforms/mattermost/adapter.py` (git rename, R071) + appended `register()` block, hook helpers, and `_standalone_send` with media upload + thread_id support. * New `plugins/platforms/mattermost/{__init__.py, plugin.yaml}` with `requires_env` / `optional_env` declarations covering MATTERMOST_URL, MATTERMOST_TOKEN, MATTERMOST_ALLOWED_USERS, MATTERMOST_ALLOW_ALL_USERS, MATTERMOST_HOME_CHANNEL, MATTERMOST_REPLY_MODE, MATTERMOST_REQUIRE_MENTION, MATTERMOST_FREE_RESPONSE_CHANNELS, MATTERMOST_ALLOWED_CHANNELS. * `gateway/config.py`: delete 17-LOC `mattermost_cfg` YAML→env bridge (moved into plugin's `_apply_yaml_config`). * `gateway/run.py::_create_adapter`: delete `Platform.MATTERMOST elif` — replaced by the existing generic plugin-registry-first dispatch. * `tools/send_message_tool.py`: delete `_send_mattermost` (22 LOC) + `Platform.MATTERMOST elif` in `_send_to_platform` — the `else` branch already routes plugin platforms through `_send_via_adapter`, which hits the registry's `standalone_sender_fn`. * `hermes_cli/setup.py`: delete `_setup_mattermost` (44 LOC) — replaced by the plugin's `interactive_setup`. * `hermes_cli/gateway.py`: delete `_PLATFORMS["mattermost"]` dict entry (3 LOC) — plugin's `setup_fn` is dispatched via the plugin path in `_configure_platform`. * Consumer rewrite: 5 test files (test_mattermost.py, test_media_download_retry.py, test_send_multiple_images.py, test_stream_consumer.py, test_ws_auth_retry.py) get `gateway.platforms.mattermost` → `plugins.platforms.mattermost.adapter` with the bulk-rewrite recipe from the platform-plugin-migration playbook. Single `mock.patch` string in test_stream_consumer.py also repointed. * `tests/tools/test_send_message_missing_platforms.py`: thin `(token, extra, chat_id, message)` compat shim around the plugin's `_standalone_send(pconfig, …)` so existing test bodies continue to work without rewriting every signature. Validation ---------- * Plugin discovery: mattermost registers from `plugins/platforms/mattermost/` alongside discord / teams / irc / line / google_chat / simplex. All 9 hooks present (setup_fn, standalone_sender_fn, apply_yaml_config_fn, is_connected, check_fn, allowed_users_env, allow_all_env, cron_deliver_env_var, max_message_length=4000). * Mattermost-touching tests: 62/62 pass (`test_mattermost.py` + `test_send_message_missing_platforms.py`). * Targeted selectors (mattermost or platform_registry or stream_consumer or ws_auth_retry or media_download_retry or send_multiple_images or send_message_tool or platform_connected): 433/433 pass. * Full sweep (`scripts/run_tests.sh tests/gateway/ tests/cron/ tests/tools/test_send_message_tool.py tests/tools/test_send_message_missing_platforms.py tests/integration/`): **6220/6220 pass in 47.8s, 0 failures**. * Lint: ruff clean on all touched files. * Git identity verified: kshitijk4poor. * Rename detection: R071 (similarity dropped from a hypothetical R09x by the ~320-line appended register block — ~36% growth over the 873-LoC base, vs Discord's 5101 LoC base which kept R091). Closes part of #3823.
49 lines
2 KiB
YAML
49 lines
2 KiB
YAML
name: mattermost-platform
|
|
label: Mattermost
|
|
kind: platform
|
|
version: 1.0.0
|
|
description: >
|
|
Mattermost gateway adapter for Hermes Agent.
|
|
Connects to a self-hosted or cloud Mattermost instance via the v4 REST
|
|
API + WebSocket event stream and relays messages between Mattermost
|
|
channels/DMs and the Hermes agent. Supports thread-mode replies, native
|
|
file uploads, channel-scoped allowlists, and home-channel cron delivery.
|
|
author: NousResearch
|
|
requires_env:
|
|
- name: MATTERMOST_URL
|
|
description: "Mattermost server URL (e.g. https://mm.example.com)"
|
|
prompt: "Mattermost server URL"
|
|
password: false
|
|
- name: MATTERMOST_TOKEN
|
|
description: "Bot account token or personal-access token"
|
|
prompt: "Mattermost bot token"
|
|
password: true
|
|
optional_env:
|
|
- name: MATTERMOST_ALLOWED_USERS
|
|
description: "Comma-separated Mattermost user IDs allowed to talk to the bot"
|
|
prompt: "Allowed users (comma-separated)"
|
|
password: false
|
|
- name: MATTERMOST_ALLOW_ALL_USERS
|
|
description: "Allow any Mattermost user to trigger the bot (dev only)"
|
|
prompt: "Allow all users? (true/false)"
|
|
password: false
|
|
- name: MATTERMOST_HOME_CHANNEL
|
|
description: "Default channel ID for cron / notification delivery"
|
|
prompt: "Home channel ID"
|
|
password: false
|
|
- name: MATTERMOST_REPLY_MODE
|
|
description: "How replies are sent: 'thread' (nested) or 'off' (flat). Default: off."
|
|
prompt: "Reply mode (thread|off)"
|
|
password: false
|
|
- name: MATTERMOST_REQUIRE_MENTION
|
|
description: "Require @bot mention in channels (default true). Set false for free-response everywhere."
|
|
prompt: "Require @mention? (true/false)"
|
|
password: false
|
|
- name: MATTERMOST_FREE_RESPONSE_CHANNELS
|
|
description: "Comma-separated channel IDs where @mention is not required."
|
|
prompt: "Free-response channel IDs (comma-separated)"
|
|
password: false
|
|
- name: MATTERMOST_ALLOWED_CHANNELS
|
|
description: "If set, the bot only responds in these channels (whitelist)."
|
|
prompt: "Allowed channel IDs (comma-separated)"
|
|
password: false
|