Skip to content

feat(buzz): honor reply_in_thread so replies can land flat in the channel - #74985

Closed
ChrisMena87 wants to merge 1 commit into
NousResearch:mainfrom
ChrisMena87:fix/buzz-reply-in-thread
Closed

ChrisMena87 wants to merge 1 commit into
NousResearch:mainfrom
ChrisMena87:fix/buzz-reply-in-thread

Conversation

@ChrisMena87

Copy link
Copy Markdown

Problem

Every Hermes reply on Buzz lands in a collapsed Thread pane instead of in the channel, which breaks the flow of the conversation for the human reading it.

The cause isn't Buzz's UI — it's that we always ask for a thread. gateway/run.py builds the stream consumer with

initial_reply_to_id=ctx.event_message_id,

with no platform condition, so every reply is anchored to the message that triggered it. The Buzz adapter turns that anchor into --reply-to, and Buzz correctly renders a threaded reply as a thread. On platforms where a reply-anchor is just a quote this is invisible; on Buzz it means the answer is one click away, every single time.

There is a reply_in_thread key already accepted per-platform in gateway/config.py (bridged into the platform config alongside reply_prefix, require_mention, etc.), but only the relay/Slack lane reads it — gateway/relay/adapter.py::_effective_reply_in_thread. Setting reply_in_thread: false under platforms.buzz today is a silent no-op: the config validates, nothing changes.

Change

Wire the existing key up in the Buzz adapter, following the same pattern require_mention already uses in this file (env var > extra > default):

platforms:
  buzz:
    extra:
      reply_in_thread: false   # answer flat in the channel

BUZZ_REPLY_IN_THREAD overrides config.yaml, same as BUZZ_REQUIRE_MENTION.

Honored in both outbound paths — send() and send_image().

Default stays True, so existing behavior is unchanged for everyone who doesn't set it.

Verification

Tested against a hosted community relay (*.communities.buzz.xyz), Hermes 0.19.0:

  • With reply_in_thread: false, the CLI invocation is ['messages', 'send', '--channel', '<id>', '--content', '-'] — no --reply-to, and replies appear in the channel.
  • With the key absent (default), --reply-to is still passed, so threading is preserved.

Notes

  • 17 lines added, 1 changed; no behavior change without opt-in.
  • Only the adapter is touched — the unconditional anchor in gateway/run.py is left alone, since other platforms rely on it.
  • Happy to add a note to website/docs/user-guide/messaging/buzz.md if you'd like the key documented in the same PR.

@alt-glitch alt-glitch added type/feature New feature or request comp/plugins Plugin system and bundled plugins area/config Config system, migrations, profiles sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades P3 Low — cosmetic, nice to have labels Jul 30, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for isolating this to the Buzz adapter; current main does pass ctx.event_message_id into the stream consumer (gateway/run.py:4192), and Buzz currently turns that target into --reply-to (plugins/platforms/buzz/adapter.py:587-590), so the premise is confirmed.

Problems

  • The new placement behavior is untested. tests/gateway/test_buzz_adapter.py:119-143 already covers adapter config precedence and :387-423 records send arguments, but this PR adds no assertions for config false, the true default, BUZZ_REPLY_IN_THREAD precedence, or the local-image branch changed at plugins/platforms/buzz/adapter.py:677.
  • The user-facing setting is undocumented: website/docs/user-guide/messaging/buzz.md:19-58 covers the canonical config and env-variable paths, and website/docs/reference/environment-variables.md:694-708 lists Buzz variables.

Suggested changes

  • Add focused adapter tests for text and local-image sends, including default/config/env precedence.
  • Document gateway.platforms.buzz.extra.reply_in_thread; if keeping the env override, document BUZZ_REPLY_IN_THREAD too.

Automated hermes-sweeper review.

return SendResult(success=False, error="Empty message")
args = ["messages", "send", "--channel", str(chat_id), "--content", "-"]
reply_target = reply_to or (metadata or {}).get("thread_id")
if not self.reply_in_thread:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please add adapter tests for the false setting, the true default, and BUZZ_REPLY_IN_THREAD precedence. tests/gateway/test_buzz_adapter.py already has config-precedence and recorded-CLI-argument patterns that can assert omission or retention of --reply-to on this exact egress path.

@teknium1

Copy link
Copy Markdown
Collaborator

Closing as implemented on main via #99429: extra.reply_in_thread: false / BUZZ_REPLY_IN_THREAD now map to reply_to_mode='off' and gate --reply-to on ALL send paths including cron standalone — a superset of this PR's send/send_image gate, same config key and env var (commit 972f031). You proposed this mechanism first; thanks for pioneering the flat-reply opt-out.

@teknium1 teknium1 closed this Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have 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 type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants