Skip to content

refactor(gateway): migrate slack/dingtalk/whatsapp/matrix/feishu/telegram/wecom/email/sms adapters to bundled plugins (salvage #41284) - #49408

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-9ffbbd87
Jun 20, 2026
Merged

refactor(gateway): migrate slack/dingtalk/whatsapp/matrix/feishu/telegram/wecom/email/sms adapters to bundled plugins (salvage #41284)#49408
teknium1 merged 2 commits into
mainfrom
hermes/hermes-9ffbbd87

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Completes the gateway-channel → plugin transition (#41112 / #3823): the last 9 inline messaging adapters — slack, dingtalk, whatsapp, matrix, feishu, telegram, wecom (+wecom_callback), email, sms — now live as self-contained bundled plugins under plugins/platforms/<x>/, discovered via the platform registry instead of hardcoded Platform.<X> factory branches.

This is a salvage of #41284 onto current main. That PR was ~1340 commits stale (opened Jun 7); gateway/run.py alone moved +2658/−5129 since (the mixin extraction), so a plain cherry-pick would have been a conflict trap. The adapter bodies were relocated with git mv (history preserved) and each migration delta re-applied surgically on current main; the core-touchpoint strips were re-done by hand against the refactored files.

Changes

  • Adapters relocated gateway/platforms/<x>.pyplugins/platforms/<x>/adapter.py (+ __init__.py/plugin.yaml). Satellites travel with their adapter: telegram_network, feishu_comment{,_rules}/feishu_meeting_invite, wecom_crypto, wecom_callback (→ callback_adapter.py).
  • register(ctx) per platform: standalone_sender_fn, apply_yaml_config_fn, setup_fn, is_connected, check_fn, plus allowed_users_env/allow_all_env/cron_deliver_env_var/max_message_length/emoji.
  • Core touchpoints stripped: gateway/run.py factory branches; gateway/config.py per-platform YAML→env blocks + connected-checker entries; hermes_cli/{gateway,setup}.py static dicts + _setup_matrix; tools/send_message_tool.py _send_<x> dispatch (now a generic _registry_standalone_send). Telegram keeps _send_telegram; matrix keeps _send_matrix_via_adapter (native-media path) with imports repointed.
  • Migration fixes carried forward: explicit enabled: false honored for plugin platforms; get_connected_platforms() forces discovery; plugin is_connected reads via gateway.get_env_value; hermes logs --component gateway matches plugins.platforms.*; matrix hidden on Windows.

Caught because main moved under the original PR

  • Matrix _apply_yaml_config was missing 4 keys the inline gateway/config.py matrix block gained in the interim — allowed_users, ignore_user_patterns, process_notices, session_scope. Deleting the inline block as-is would have silently dropped them; ported into the plugin hook and live-verified.
  • ~12 test files added on main since the PR base still imported gateway.platforms.* (incl. from gateway.platforms import X as Y and source-by-path reads in test_telegram_webhook_secret / test_windows_native_support). Swept all import forms + retargeted the source-path tests.

Validation

Result
Live discovery E2E all 10 platforms register + resolve via registry; legacy modules gone; other plugins (discord/mattermost/line/photon/raft/…) intact
Setup/status listing all 10 surface in _all_platforms() with correct labels/emojis/token vars
ruff clean
Test sweep (gateway + tools + cli + logging + e2e) 7539 passed, 7 failed
The 7 failures test_matrix_voice (6, mautrix SDK skew in the local env) + test_telegram_group_gating::test_config_bridges_telegram_group_settings (1, pre-existing intra-file env leak) — both fail identically on pristine origin/main, unrelated to this change

Scope

Deliberately not migrated (same policy as prior migrations): webhook, api_server, msgraph_webhook (generic HTTP ingress), whatsapp_cloud, and signal/qqbot/weixin/yuanbao/bluebubbles (open contributor migration PRs preserve that work).

Infographic

gateway adapters to plugins migration

@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-9ffbbd87 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11264 on HEAD, 11228 on base (🆕 +36)

🆕 New issues (216):

Rule Count
unresolved-attribute 93
unresolved-import 72
invalid-method-override 17
invalid-argument-type 11
invalid-assignment 10
invalid-return-type 3
call-non-callable 3
unresolved-reference 3
not-subscriptable 1
unused-type-ignore-comment 1
no-matching-overload 1
invalid-raise 1
First entries
plugins/platforms/feishu/adapter.py:3537: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_last_chunk_len` on type `MessageEvent`
plugins/platforms/email/adapter.py:799: [invalid-method-override] invalid-method-override: Invalid override of method `send_document`: Definition is incompatible with `BasePlatformAdapter.send_document`
plugins/platforms/feishu/adapter.py:1370: [unresolved-import] unresolved-import: Cannot resolve imported module `lark_oapi.core.model`
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
plugins/platforms/matrix/adapter.py:1246: [unresolved-import] unresolved-import: Cannot resolve imported module `mautrix.crypto`
plugins/platforms/wecom/adapter.py:1465: [invalid-method-override] invalid-method-override: Invalid override of method `send_voice`: Definition is incompatible with `BasePlatformAdapter.send_voice`
plugins/platforms/wecom/adapter.py:180: [unresolved-attribute] unresolved-attribute: Attribute `ClientWebSocketResponse` is not defined on `None` in union `Unknown | None`
plugins/platforms/dingtalk/adapter.py:1063: [unresolved-attribute] unresolved-attribute: Attribute `CreateCardRequestImGroupOpenSpaceModel` is not defined on `None` in union `Unknown | None`
plugins/platforms/whatsapp/adapter.py:1030: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_last_chunk_len` on type `MessageEvent`
plugins/platforms/wecom/adapter.py:739: [not-subscriptable] not-subscriptable: Cannot subscript object of type `None` with no `__getitem__` method
plugins/platforms/email/adapter.py:282: [invalid-argument-type] invalid-argument-type: Argument to function `cache_image_from_bytes` is incorrect: Expected `bytes`, found `(Message[str, str] & ~AlwaysFalsy) | (bytes & ~AlwaysFalsy) | (Any & ~AlwaysFalsy)`
plugins/platforms/telegram/adapter.py:2226: [unresolved-import] unresolved-import: Module `telegram` has no member `BotCommandScopeDefault`
plugins/platforms/dingtalk/adapter.py:1209: [unresolved-attribute] unresolved-attribute: Attribute `StreamingUpdateHeaders` is not defined on `None` in union `Unknown | None`
plugins/platforms/matrix/adapter.py:700: [unresolved-import] unresolved-import: Cannot resolve imported module `mautrix.types`
plugins/platforms/dingtalk/adapter.py:1114: [unresolved-attribute] unresolved-attribute: Attribute `DeliverCardHeaders` is not defined on `None` in union `Unknown | None`
plugins/platforms/feishu/feishu_comment.py:40: [unresolved-import] unresolved-import: Cannot resolve imported module `lark_oapi.core.enum`
plugins/platforms/wecom/callback_adapter.py:135: [unresolved-attribute] unresolved-attribute: Attribute `Application` is not defined on `None` in union `Unknown | None`
plugins/platforms/feishu/adapter.py:77: [unresolved-import] unresolved-import: Cannot resolve imported module `aiohttp`
plugins/platforms/dingtalk/adapter.py:1258: [unresolved-attribute] unresolved-attribute: Attribute `RobotRecallEmotionRequestTextEmotion` is not defined on `None` in union `Unknown | None`
plugins/platforms/telegram/adapter.py:2113: [unresolved-attribute] unresolved-attribute: Attribute `VOICE` is not defined on `None` in union `Unknown | None`
plugins/platforms/dingtalk/adapter.py:136: [unresolved-import] unresolved-import: Cannot resolve imported module `dingtalk_stream`
plugins/platforms/dingtalk/adapter.py:1068: [unresolved-attribute] unresolved-attribute: Attribute `CreateCardRequestImRobotOpenSpaceModel` is not defined on `None` in union `Unknown | None`
plugins/platforms/dingtalk/adapter.py:287: [unresolved-attribute] unresolved-attribute: Attribute `Config` is not defined on `None` in union `Unknown | None`
plugins/platforms/dingtalk/adapter.py:1276: [unresolved-attribute] unresolved-attribute: Attribute `RobotReplyEmotionRequestTextEmotion` is not defined on `None` in union `Unknown | None`
plugins/platforms/dingtalk/adapter.py:1265: [unresolved-attribute] unresolved-attribute: Attribute `RobotRecallEmotionRequest` is not defined on `None` in union `Unknown | None`
... and 191 more

✅ Fixed issues (196):

Rule Count
unresolved-attribute 87
unresolved-import 62
invalid-method-override 17
invalid-argument-type 10
invalid-assignment 8
invalid-return-type 3
call-non-callable 3
unresolved-reference 2
unused-type-ignore-comment 1
not-subscriptable 1
invalid-raise 1
no-matching-overload 1
First entries
gateway/platforms/telegram.py:145: [unresolved-import] unresolved-import: Cannot resolve imported module `telegram.request`
gateway/platforms/telegram.py:138: [unresolved-import] unresolved-import: Cannot resolve imported module `telegram.ext`
gateway/platforms/wecom_callback.py:25: [unresolved-import] unresolved-import: Cannot resolve imported module `defusedxml.ElementTree`
gateway/platforms/dingtalk.py:1056: [unresolved-attribute] unresolved-attribute: Attribute `CreateCardRequestImGroupOpenSpaceModel` is not defined on `None` in union `Unknown | None`
gateway/platforms/feishu.py:1358: [unresolved-import] unresolved-import: Cannot resolve imported module `lark_oapi.api.application.v6`
gateway/platforms/telegram.py:3561: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to `def group_providers(slugs) -> Unknown`
gateway/platforms/dingtalk.py:1202: [unresolved-attribute] unresolved-attribute: Attribute `StreamingUpdateHeaders` is not defined on `None` in union `Unknown | None`
gateway/platforms/slack.py:91: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_bolt.async_app`
gateway/platforms/telegram.py:6077: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_last_chunk_len` on type `MessageEvent`
gateway/platforms/feishu.py:83: [unresolved-import] unresolved-import: Cannot resolve imported module `websockets`
gateway/platforms/slack.py:3698: [unresolved-import] unresolved-import: Cannot resolve imported module `httpx`
gateway/platforms/wecom.py:180: [unresolved-attribute] unresolved-attribute: Attribute `ClientWebSocketResponse` is not defined on `None` in union `Unknown | None`
gateway/platforms/feishu_comment.py:40: [unresolved-import] unresolved-import: Cannot resolve imported module `lark_oapi.core.enum`
gateway/platforms/dingtalk.py:1251: [unresolved-attribute] unresolved-attribute: Attribute `RobotRecallEmotionRequestTextEmotion` is not defined on `None` in union `Unknown | None`
gateway/platforms/email.py:215: [unresolved-attribute] unresolved-attribute: Attribute `decode` is not defined on `Message[str, str] & ~AlwaysFalsy` in union `(Message[str, str] & ~AlwaysFalsy) | (bytes & ~AlwaysFalsy) | (Any & ~AlwaysFalsy)`
gateway/platforms/telegram.py:6208: [invalid-assignment] invalid-assignment: Object of type `str | None` is not assignable to attribute `text` of type `str`
gateway/platforms/telegram.py:2995: [unresolved-attribute] unresolved-attribute: Attribute `send_message` is not defined on `None` in union `Unknown | None`
gateway/platforms/dingtalk.py:1061: [unresolved-attribute] unresolved-attribute: Attribute `CreateCardRequestImRobotOpenSpaceModel` is not defined on `None` in union `Unknown | None`
gateway/platforms/dingtalk.py:280: [unresolved-attribute] unresolved-attribute: Attribute `Config` is not defined on `None` in union `Unknown | None`
gateway/platforms/telegram.py:4269: [unresolved-attribute] unresolved-attribute: Attribute `MARKDOWN_V2` is not defined on `None` in union `Unknown | None`
gateway/platforms/dingtalk.py:1269: [unresolved-attribute] unresolved-attribute: Attribute `RobotReplyEmotionRequestTextEmotion` is not defined on `None` in union `Unknown | None`
gateway/platforms/whatsapp.py:890: [invalid-method-override] invalid-method-override: Invalid override of method `send_voice`: Definition is incompatible with `BasePlatformAdapter.send_voice`
gateway/platforms/whatsapp.py:1030: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_last_chunk_len` on type `MessageEvent`
gateway/platforms/telegram.py:4113: [unresolved-attribute] unresolved-attribute: Attribute `PRIVATE` is not defined on `None` in union `Unknown | None`
gateway/platforms/dingtalk.py:1258: [unresolved-attribute] unresolved-attribute: Attribute `RobotRecallEmotionRequest` is not defined on `None` in union `Unknown | None`
... and 171 more

Unchanged: 5690 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/refactor Code restructuring, no behavior change comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists labels Jun 20, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #41284 (the ~1340-commit-stale predecessor this salvages onto current main), #41112 / #3823 (the gateway-channel to plugin transition this completes). Salvage PR — supersedes the stale #41284 with history-preserving git mv relocations re-applied against the refactored gateway/run.py.

teknium1 added 2 commits June 20, 2026 10:06
…gram/wecom/email/sms adapters to bundled plugins

Salvage of PR #41284 onto current main. Relocates the last 9 inline messaging
adapters (+ satellites: telegram_network, feishu_comment/_rules/meeting_invite,
wecom_crypto, wecom_callback) from gateway/platforms/ into self-contained
bundled plugins under plugins/platforms/<x>/, discovered via the platform
registry. Strips the per-platform core touchpoints from gateway/run.py,
gateway/config.py, hermes_cli/gateway.py, hermes_cli/setup.py, and
tools/send_message_tool.py.

Carries forward the migration fixes (explicit enabled:false honored,
get_connected_platforms forces discovery, plugin is_connected via
gateway.get_env_value, logs --component gateway matches plugins.platforms.*,
matrix hidden on Windows).

Additionally ports config keys main added since the PR base: the matrix
plugin's _apply_yaml_config now also covers allowed_users,
ignore_user_patterns, process_notices, and session_scope (the inline
gateway/config.py matrix block gained these in the 1340 commits the PR sat
open; they would otherwise have been silently dropped on deletion).
test_telegram_webhook_secret reads telegram adapter source by path; point it
at plugins/platforms/telegram/adapter.py. test_windows_native_support
npm-spawn parametrization referenced gateway/platforms/whatsapp.py; point it at
plugins/platforms/whatsapp/adapter.py.
@teknium1
teknium1 force-pushed the hermes/hermes-9ffbbd87 branch from 66830f1 to a2da1b0 Compare June 20, 2026 17:07
@teknium1
teknium1 merged commit c329279 into main Jun 20, 2026
35 checks passed
@teknium1
teknium1 deleted the hermes/hermes-9ffbbd87 branch June 20, 2026 17:26
santhiprakash added a commit to santhiprakash/hermes-agent that referenced this pull request Jul 29, 2026
- Problem: The tools-reference page references gateway/platforms/feishu_comment.py, but the feishu adapter was migrated to plugins/platforms/feishu/ in the platform-plugin migration (NousResearch#49408).
- Fix: Update the path to plugins/platforms/feishu/feishu_comment.py to match the current codebase.
- Verification: Confirmed target file exists at the new path and the old path no longer exists in gateway/platforms/.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants