refactor(gateway): migrate Slack adapter to bundled plugin - #41160
Closed
teknium1 wants to merge 2 commits into
Closed
refactor(gateway): migrate Slack adapter to bundled plugin#41160teknium1 wants to merge 2 commits into
teknium1 wants to merge 2 commits into
Conversation
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
5 |
invalid-method-override |
4 |
invalid-assignment |
3 |
invalid-return-type |
2 |
unresolved-attribute |
2 |
call-non-callable |
1 |
invalid-raise |
1 |
First entries
tools/send_message_tool.py:830: [invalid-assignment] invalid-assignment: Invalid subscript assignment with key of type `Literal["warnings"]` and value of type `list[str | Unknown]` on object of type `dict[str, str]`
plugins/platforms/slack/adapter.py:3414: [invalid-return-type] invalid-return-type: Function can implicitly return `None`, which is not assignable to return type `str`
plugins/platforms/slack/adapter.py:1709: [invalid-method-override] invalid-method-override: Invalid override of method `send_image_file`: Definition is incompatible with `BasePlatformAdapter.send_image_file`
plugins/platforms/slack/adapter.py:89: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_bolt.async_app`
plugins/platforms/slack/adapter.py:832: [call-non-callable] call-non-callable: Object of type `<special-form 'typing.Any'>` is not callable
tests/tools/test_signal_media.py:186: [invalid-assignment] invalid-assignment: Object of type `((...) -> Awaitable[dict[Unknown, Unknown]]) | None` is not assignable to attribute `standalone_sender_fn` on type `PlatformEntry | None`
plugins/platforms/slack/adapter.py:3470: [invalid-return-type] invalid-return-type: Function can implicitly return `None`, which is not assignable to return type `bytes`
plugins/platforms/slack/adapter.py:3472: [unresolved-import] unresolved-import: Cannot resolve imported module `httpx`
plugins/platforms/slack/adapter.py:1891: [invalid-method-override] invalid-method-override: Invalid override of method `send_document`: Definition is incompatible with `BasePlatformAdapter.send_document`
tests/tools/test_signal_media.py:174: [invalid-assignment] invalid-assignment: Object of type `AsyncMock` is not assignable to attribute `standalone_sender_fn` on type `PlatformEntry | None`
plugins/platforms/slack/adapter.py:90: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_bolt.adapter.socket_mode.async_handler`
tests/tools/test_signal_media.py:173: [unresolved-attribute] unresolved-attribute: Attribute `standalone_sender_fn` is not defined on `None` in union `PlatformEntry | None`
plugins/platforms/slack/adapter.py:1935: [invalid-raise] invalid-raise: Cannot raise object of type `None | Exception`: Not an instance or subclass of `BaseException`
plugins/platforms/slack/adapter.py:1833: [invalid-method-override] invalid-method-override: Invalid override of method `send_video`: Definition is incompatible with `BasePlatformAdapter.send_video`
plugins/platforms/slack/adapter.py:1135: [invalid-method-override] invalid-method-override: Invalid override of method `send_private_notice`: Definition is incompatible with `BasePlatformAdapter.send_private_notice`
plugins/platforms/slack/adapter.py:91: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_sdk.web.async_client`
plugins/platforms/slack/adapter.py:3644: [unresolved-import] unresolved-import: Cannot resolve imported module `aiohttp`
plugins/platforms/slack/adapter.py:1055: [unresolved-attribute] unresolved-attribute: Attribute `client` is not defined on `None` in union `Any | None`
✅ Fixed issues (14):
| Rule | Count |
|---|---|
unresolved-import |
5 |
invalid-method-override |
4 |
invalid-return-type |
2 |
call-non-callable |
1 |
invalid-raise |
1 |
unresolved-attribute |
1 |
First entries
gateway/platforms/slack.py:1709: [invalid-method-override] invalid-method-override: Invalid override of method `send_image_file`: Definition is incompatible with `BasePlatformAdapter.send_image_file`
gateway/platforms/slack.py:89: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_bolt.async_app`
gateway/platforms/slack.py:1891: [invalid-method-override] invalid-method-override: Invalid override of method `send_document`: Definition is incompatible with `BasePlatformAdapter.send_document`
gateway/platforms/slack.py:92: [unresolved-import] unresolved-import: Cannot resolve imported module `aiohttp`
gateway/platforms/slack.py:90: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_bolt.adapter.socket_mode.async_handler`
gateway/platforms/slack.py:3470: [invalid-return-type] invalid-return-type: Function can implicitly return `None`, which is not assignable to return type `bytes`
gateway/platforms/slack.py:3414: [invalid-return-type] invalid-return-type: Function can implicitly return `None`, which is not assignable to return type `str`
gateway/platforms/slack.py:832: [call-non-callable] call-non-callable: Object of type `<special-form 'typing.Any'>` is not callable
gateway/platforms/slack.py:1833: [invalid-method-override] invalid-method-override: Invalid override of method `send_video`: Definition is incompatible with `BasePlatformAdapter.send_video`
gateway/platforms/slack.py:1135: [invalid-method-override] invalid-method-override: Invalid override of method `send_private_notice`: Definition is incompatible with `BasePlatformAdapter.send_private_notice`
gateway/platforms/slack.py:91: [unresolved-import] unresolved-import: Cannot resolve imported module `slack_sdk.web.async_client`
gateway/platforms/slack.py:3472: [unresolved-import] unresolved-import: Cannot resolve imported module `httpx`
gateway/platforms/slack.py:1935: [invalid-raise] invalid-raise: Cannot raise object of type `None | Exception`: Not an instance or subclass of `BaseException`
gateway/platforms/slack.py:1055: [unresolved-attribute] unresolved-attribute: Attribute `client` is not defined on `None` in union `Any | None`
Unchanged: 5176 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
Move gateway/platforms/slack.py into plugins/platforms/slack/ following the Discord (#24356) and Home Assistant (#40709) migrations. Advances #41112 / hardcoded Platform.SLACK touchpoints in core. - Adapter file renamed via git mv (history preserved). - register() exposes the platform via ctx.register_platform() instead of the Platform.SLACK elif in gateway/run.py::_create_adapter(). - _standalone_send() replaces the legacy _send_slack() helper in tools/send_message_tool.py; out-of-process cron delivery (deliver=slack) now flows through the registry's standalone_sender_fn. mrkdwn formatting moved into the plugin (was applied in _send_to_platform before chunking). - _apply_yaml_config() owns the config.yaml slack: -> SLACK_* env bridge (require_mention, strict_mention, allow_bots, free_response_channels, reactions, allowed_channels), replacing the hardcoded block in gateway/config.py. - interactive_setup() replaces hermes_cli/setup.py::_setup_slack + _write_slack_manifest_and_instruct and the static _PLATFORMS["slack"] dict in hermes_cli/gateway.py; setup metadata is discovered dynamically. - is_connected() probes SLACK_BOT_TOKEN via hermes_cli.gateway.get_env_value. - max_message_length=39000 on the PlatformEntry; the registry fallback in send_message_tool covers it (dropped the _MAX_LENGTHS entry). The SLACK_BOT_TOKEN/SLACK_HOME_CHANNEL env->PlatformConfig seeding and the _is_user_authorized allowlist maps stay in core (same as Discord/HA/Mattermost). Bug fixed during migration: the registry-driven plugin-enable pass in _apply_env_overrides re-enabled any plugin platform whose is_connected() passed, ignoring an explicit enabled: false. Slack is the first plugin with an enabled-false-wins test, so it exposed this latent bug (Discord had no such test). Added an explicit-disable guard (_enabled_explicit + enabled=False -> skip) and changed the slack env-block to read the flag instead of popping it so the guard can see it; the flag is still cleared in the final per-platform cleanup. Restores test_explicit_{top_level,platforms}_slack_enabled_false_wins. Test imports rewritten across 11 files (gateway.platforms.slack -> plugins.platforms.slack.adapter). The _setup_slack home-channel tests moved to tests/gateway/test_slack_plugin_setup.py exercising interactive_setup. The test_send_message_tool slack-formatting tests now patch the registry standalone_sender_fn (via _patch_slack_standalone_sender) and assert the mrkdwn-formatted text reaches the wire. Validation: 706 targeted tests pass (slack/config/setup/registry/send/media suites); 18/18 live E2E checks pass (real plugin discovery + registry resolves SlackAdapter, env-only enable, standalone sender wired, YAML bridge, dynamic setup discovery).
teknium1
force-pushed
the
hermes/hermes-87ac0a8e
branch
from
June 7, 2026 14:05
afe5b88 to
c2eae47
Compare
…ge (#f6f363662) Pre-existing main breakage inherited via rebase, not slack-migration fallout: f6f3636 made discord component-button auth fail closed when no allowlist is set but only updated test_discord_component_auth.py. test_discord_model_picker and two test_discord_clarify_buttons tests drove the authorized-proceed path with an empty allowlist, which now correctly rejects. Give the interacting user an allowlist entry so the proceed path runs (dedicated *_unauthorized_* tests still cover rejection). Same fix as #41284; both PRs un-break main's currently-red CI.
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Slack is now a bundled plugin (
plugins/platforms/slack/) discovered via the platform registry instead of hardcodedPlatform.SLACKtouchpoints in core — the same shape as the Discord (#24356) and Home Assistant (#40709) migrations. Advances #41112 / #3823.Changes
gateway/platforms/slack.py→plugins/platforms/slack/adapter.py(git rename, history preserved) +__init__.py/plugin.yaml.register(ctx)replaces thePlatform.SLACKelif ingateway/run.py::_create_adapter()._standalone_send()replaces the legacy_send_slack()intools/send_message_tool.py;deliver=slackcron delivery now flows through the registry'sstandalone_sender_fn. mrkdwn formatting moved into the plugin._apply_yaml_config()owns theconfig.yamlslack:→SLACK_*env bridge (require_mention, strict_mention, allow_bots, free_response_channels, reactions, allowed_channels), replacing the hardcoded block ingateway/config.py.interactive_setup()replaceshermes_cli/setup.py::_setup_slack+ the static_PLATFORMS["slack"]dict inhermes_cli/gateway.py; setup metadata is discovered dynamically.is_connected()probesSLACK_BOT_TOKEN;max_message_length=39000on thePlatformEntry(registry fallback covers it — dropped the_MAX_LENGTHSentry).PlatformConfigseeding and the_is_user_authorizedallowlist maps stay in core (same as Discord/HA/Mattermost).Bug fixed during migration
The registry-driven plugin-enable pass in
_apply_env_overridesre-enabled any plugin platform whoseis_connected()passed, ignoring an explicitenabled: false. Slack is the first plugin with anenabled-false-winstest, so it exposed this latent bug (Discord had no such test). Added an explicit-disable guard (_enabled_explicit+enabled=False→ skip) and switched the slack env-block to read (not pop) the flag so the guard can see it; the flag is still cleared in the final per-platform cleanup.Validation
test_explicit_{top_level,platforms}_slack_enabled_false_winsSlackAdapter, env-only enable, standalone sender wired, YAML bridge, dynamic setup discovery)Test imports rewritten across 11 files (
gateway.platforms.slack→plugins.platforms.slack.adapter). The_setup_slackhome-channel tests moved totests/gateway/test_slack_plugin_setup.py(exercisinginteractive_setup); the slack-formatting tests intest_send_message_toolnow patch the registrystandalone_sender_fnand assert the mrkdwn text reaches the wire.Infographic