Skip to content

feat(slack): make bot mention stripping configurable - #47536

Closed
replygirl wants to merge 1 commit into
NousResearch:mainfrom
replygirl:fix/slack-strip-bot-mentions
Closed

feat(slack): make bot mention stripping configurable#47536
replygirl wants to merge 1 commit into
NousResearch:mainfrom
replygirl:fix/slack-strip-bot-mentions

Conversation

@replygirl

@replygirl replygirl commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add Slack strip_bot_mentions config, defaulting to true to preserve existing behavior
  • allow strip_bot_mentions: false to keep raw <@U...> bot mention tokens in current message text, fetched thread context, and thread-parent reply_to_text
  • bridge the YAML setting into Slack platform extra config and SLACK_STRIP_BOT_MENTIONS env fallback

Rationale / example scenario

In a shared Slack channel with two Hermes gateway profiles installed, a user might write:

<@U_DEFAULT_HERMES> can you check the deployment?

while another Hermes bot/profile is also participating in the same thread. If the Slack adapter strips <@U_DEFAULT_HERMES> before the model sees the message, I only receive can you check the deployment?. That loses the key evidence for who was explicitly addressed.

An even more ambiguous case is a message that mentions one bot/profile but is addressed to another:

<@U_DEFAULT_HERMES> can you check on <@U_OTHER_HERMES>'s deployment?

If the addressed mention is stripped, the model sees only can you check on <@U_OTHER_HERMES>'s deployment?. In a multi-bot thread, that can look like the remaining mentioned bot/profile is the intended addressee, even though the user was actually asking the default Hermes bot to inspect something belonging to the other profile.

Preserving the raw mention tokens when strip_bot_mentions: false gives the model the same routing clues Slack had at the adapter layer, so it can distinguish between:

  • a request addressed to this bot;
  • a request addressed to another Hermes profile;
  • a request addressed to one bot about another bot/profile;
  • a general thread reply that should not wake every bot that has prior context.

The default remains true, so existing single-bot workspaces keep the current cleaned-up prompt text unless they opt into preserving mentions.

Test plan

  • python -m pytest tests/gateway/test_slack.py tests/gateway/test_slack_approval_buttons.py tests/gateway/test_slack_mention.py -q -o 'addopts='
  • git diff --check
  • python -m py_compile gateway/platforms/slack.py gateway/config.py tests/gateway/test_slack.py tests/gateway/test_slack_approval_buttons.py tests/gateway/test_slack_mention.py tests/conftest.py

Copilot AI review requested due to automatic review settings June 17, 2026 01:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery platform/slack Slack app adapter P3 Low — cosmetic, nice to have labels Jun 17, 2026
@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying the multi-bot routing ambiguity. The behavior is still present on current main: the active Slack adapter unconditionally strips the addressed bot token from inbound text (plugins/platforms/slack/adapter.py:2870-2872), thread context (:3792-3794), and parent reply context (:3890-3894).

Problems

  • The PR edits gateway/platforms/slack.py, but commit 5600105478ffde29d7566b45421b100eaa29c4ef moved the active adapter to plugins/platforms/slack/adapter.py; the proposed runtime edits need to be salvaged into that plugin.
  • Slack YAML translation is now plugin-owned: gateway/config.py:1269-1309 dispatches plugins/platforms/slack/adapter.py::_apply_yaml_config (:4485-4519). The new setting belongs in that hook rather than a restored core Slack-specific block.
  • Please document the new user-facing setting alongside the Slack mention configuration at website/docs/user-guide/messaging/slack.md:383-419.

Suggested changes

  • Port the resolver, the three stripping gates, and regression tests to the migrated plugin paths; preserve config.yaml as the user-facing mechanism and use the plugin bridge only for its existing internal environment-backed runtime model.

Automated hermes-sweeper review.

@@ -2522,9 +2522,10 @@ async def _handle_slack_message(self, event: dict) -> None:
):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current main migrated the active Slack adapter to plugins/platforms/slack/adapter.py in 5600105478ffde29d7566b45421b100eaa29c4ef; salvage this guard and the other stripping sites into that plugin path so the change reaches the live adapter.

Comment thread gateway/config.py
@@ -1037,6 +1039,8 @@ def _merge_platform_map(source_platforms: Any) -> None:
os.environ["SLACK_REQUIRE_MENTION"] = str(slack_cfg["require_mention"]).lower()
if "strict_mention" in slack_cfg and not os.getenv("SLACK_STRICT_MENTION"):
os.environ["SLACK_STRICT_MENTION"] = str(slack_cfg["strict_mention"]).lower()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current main delegates Slack YAML-to-environment translation to plugins/platforms/slack/adapter.py::_apply_yaml_config (gateway/config.py:1269-1309). Add this bridge to that plugin hook rather than the removed core Slack configuration block.

@teknium1

Copy link
Copy Markdown
Contributor

Closing as superseded by #69483 (merged): the goal (agent sees who's mentioned) is solved by #69320's mention humanization + identity grounding, merged earlier today; keeping raw <@U…> tokens would now conflict with humanization.

Thanks for the work — it's credited in #69483's summary.

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 P3 Low — cosmetic, nice to have platform/slack Slack app adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants