Skip to content

feat(gateway): auto_thread only creates threads on @mention - #8597

Open
zocs wants to merge 1 commit into
NousResearch:mainfrom
zocs:feat/discord-auto-thread-on-mention-only
Open

feat(gateway): auto_thread only creates threads on @mention#8597
zocs wants to merge 1 commit into
NousResearch:mainfrom
zocs:feat/discord-auto-thread-on-mention-only

Conversation

@zocs

@zocs zocs commented Apr 12, 2026

Copy link
Copy Markdown

What

auto_thread currently creates a thread for every message that triggers a response, regardless of whether the bot was @mentioned. This makes it impossible to use require_mention=false + auto_thread=true without getting a thread for every single message.

This PR adds mention-awareness to auto_thread: threads are only created when the bot was actually @mentioned. Non-mentioned messages reply directly in the channel.

Why

Users want flexible Discord channel usage: casual conversation flows naturally in the channel without creating unnecessary thread partitions, while @mentions signal a need for organized tracking — like following up on a specific project or topic — and should automatically spawn a thread.

Currently there's no way to achieve this. The only options are:

  • auto_thread: true → every message creates a thread (noisy)
  • auto_thread: false → no threads at all (no organization)

The documentation already describes the intended behavior as "every @mention automatically creates a new thread", but the implementation didn't distinguish between mentioned and non-mentioned messages.

How to test

  1. Set in config.yaml:
    discord:
      require_mention: false
      auto_thread: true
  2. Send a message without @mention → bot replies directly in channel
  3. Send a message with @mention → bot creates a thread and replies there

Test results

Full test suite on both main and feature branch:

  • main: 78 failed, 10868 passed, 35 skipped
  • feature branch: 71 failed, 10875 passed, 35 skipped

All 71 failures on the feature branch are pre-existing (voice, approval, provider parity, etc.) — none are related to this change. The 7 additional passes are from fixing existing broken Discord tests to match the new behavior.

Discord-specific tests: 207 passed, 0 failed — verified on two independent systems.

System OS Python Result
CachyOS Arch-based 3.11 207 passed
MX Linux Debian GNU/Linux 13 (trixie) 3.13 207 passed

Demo

auto-thread-on-mention-demo

  • Top: Non-@mentioned message ("Hi! Hermes") → bot replies directly in channel
  • Bottom: @mentioned message ("Hi! Let's do a auto thread test @Hermes") → bot auto-creates a thread and replies there

Platforms tested

  • CachyOS (Arch-based), Python 3.11, Discord gateway
  • Debian GNU/Linux 13 (trixie), Python 3.13, Discord gateway

…messages

When require_mention=false and auto_thread=true, the bot was creating
threads for every message instead of only @mentioned messages. This made
it impossible to have a flexible setup where non-mentioned messages get
direct channel replies while @mentions open threads.

The code now tracks whether the bot was actually mentioned and only
triggers auto_thread creation when was_mentioned is true. This aligns
the implementation with the documented behavior ('every @mention
automatically creates a new thread').

Tested on Linux (CachyOS) with Discord.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have platform/discord Discord bot adapter comp/gateway Gateway runner, session dispatch, delivery labels Apr 28, 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 mismatch between the Discord docs and routing behavior. The premise still holds on current main: plugins/platforms/discord/adapter.py:6226-6227 creates a thread without an explicit-mention predicate, while hermes_cli/config.py:2430 and website/docs/user-guide/messaging/discord.md:285 describe mention-triggered threading.

Problems

  • The PR changes gateway/platforms/discord.py, but current main moved the active adapter to plugins/platforms/discord/adapter.py in cc8e5ec2a; this needs a targeted port rather than a direct merge.
  • The added was_mentioned check at gateway/platforms/discord.py:2283 only uses resolved message.mentions. Current main's _self_is_explicitly_mentioned() also accepts raw <@ID> / <@!ID> tokens when Discord leaves that list empty (plugins/platforms/discord/adapter.py:4852-4863). Preserve that behavior when porting.
  • Please add the missing negative regression: with require_mention=false, an unmentioned top-level message must remain a parent-channel reply and never await _auto_create_thread.

This is an automated hermes-sweeper review.

return

if self._client.user and self._client.user in message.mentions:
was_mentioned = self._client.user and self._client.user in message.mentions

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.

Please use the current explicit-mention helper when salvaging this condition. Main now treats raw <@ID> / <@!ID> content as a mention even when Discord leaves message.mentions empty (plugins/platforms/discord/adapter.py:4852-4863), so this resolved-list-only predicate would regress that route.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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 12, 2026

@GottZ GottZ 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.

This was generated by AI during triage.

Summary

Two PRs address the same Discord auto-threading mismatch with identical diffs: both gate thread creation on whether the bot appears in message.mentions and update positive mention-path tests, but neither includes the required negative regression for an unmentioned top-level message. Neither PR has a recorded Verify verdict.

Related pull requests

  • #8579 [closed] duplicate — (+38/-14) — superseded by #8597: The diff makes auto-threading mention-aware via a was_mentioned predicate and updates existing tests to send mentions, but it does not test that an unmentioned message remains in the parent channel. This closed PR remains relevant as the source-equivalent predecessor of #8597.
  • #8597 related — (+38/-14) — keep open, but do not merge as-is: Consistent with the contributor's keep_open review, the behavioral premise is valid, but the diff targets the obsolete gateway/platforms/discord.py path rather than the active plugins/platforms/discord/adapter.py, relies only on message.mentions instead of preserving raw <@id>/<@!ID> detection, and lacks the negative unmentioned-message regression.

Duplicates

#8579 and #8597 contain essentially the same implementation and test changes; #8579 is the closed predecessor superseded by #8597.

Suggested consolidation

Consolidate on #8597 and keep #8579 closed as its duplicate; merge #8597 only after porting the change to the active adapter, using the existing explicit-mention helper so raw mention tokens remain supported, and adding the negative regression requested in the contributor keep_open review.

Complex graph

flowchart LR
    classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
    classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
    classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
    classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
    classDef best stroke-width:3px,stroke:#b45309
    classDef target stroke-width:3px,stroke:#4338ca
    subgraph Dup8579 ["PRs duplicating each other"]
        P8579["PR #8579 (closed)"]
        P8597["PR #8597 (open)"]
    end
    class P8579 closed
    class P8597 open
    class P8597 target
    click P8579 "https://github.com/NousResearch/hermes-agent/pull/8579"
    click P8597 "https://github.com/NousResearch/hermes-agent/pull/8597"
Loading

Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed or no verify verdict yet (state tag in the node label).

Cross-PR triage: Reviewed 2 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 15 kB of PR diffs, 4 kB of issue/PR text, 1 kB of discussion (2 comments), 1 verify verdict. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

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/discord Discord bot 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-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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