hermes - 💡(How to fix) Fix [Feature]: Multi-Agent Discord channel collaboration — history injection + cascade prevention [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#14853Fetched 2026-04-24 06:14:24
View on GitHub
Comments
2
Participants
2
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
labeled ×4commented ×2mentioned ×1subscribed ×1

We run a multi-agent Discord setup (3 specialized Hermes instances in separate systemd services, each with its own profile, persona, and model). The biggest pain point: agents in shared channels have no visibility into each other's messages, making collaborative workflows impossible without triggering response cascades.

We built a working solution and want to share the approach for potential upstreaming. Related to #13054 (which proposes the same history injection) but we also solved the cascade prevention and mention-gating problems that come with multi-bot shared channels.

Error Message

PATCH: inject recent channel history as context so agents can see

each other's messages without needing to trigger each other.

Controlled by DISCORD_CHANNEL_HISTORY_SIZE (0 = disabled).

_history_size = int(os.getenv("DISCORD_CHANNEL_HISTORY_SIZE", "0")) if _history_size > 0: try: _history_lines = [] async for _m in _chan.history(limit=_history_size, before=message): _author = _m.author.display_name or _m.author.name if _m.content: _history_lines.append(f"[{_author}]: {_m.content}") if _history_lines: _history_block = "Recent channel history (oldest to newest):\n" + "\n".join(reversed(_history_lines)) _channel_prompt = (_history_block + "\n\n" + _channel_prompt).strip() if _channel_prompt else _history_block except Exception: pass

Root Cause

We run a multi-agent Discord setup (3 specialized Hermes instances in separate systemd services, each with its own profile, persona, and model). The biggest pain point: agents in shared channels have no visibility into each other's messages, making collaborative workflows impossible without triggering response cascades.

We built a working solution and want to share the approach for potential upstreaming. Related to #13054 (which proposes the same history injection) but we also solved the cascade prevention and mention-gating problems that come with multi-bot shared channels.

Fix Action

Fix / Workaround

A small patch in _handle_message that fetches the last N messages from Discord channel history and prepends them to the channel prompt:

# PATCH: inject recent channel history as context so agents can see
# each other's messages without needing to trigger each other.
# Controlled by DISCORD_CHANNEL_HISTORY_SIZE (0 = disabled).
_history_size = int(os.getenv("DISCORD_CHANNEL_HISTORY_SIZE", "0"))
if _history_size > 0:
    try:
        _history_lines = []
        async for _m in _chan.history(limit=_history_size, before=message):
            _author = _m.author.display_name or _m.author.name
            if _m.content:
                _history_lines.append(f"[{_author}]: {_m.content}")
        if _history_lines:
            _history_block = "Recent channel history (oldest to newest):\n" + "\n".join(reversed(_history_lines))
            _channel_prompt = (_history_block + "\n\n" + _channel_prompt).strip() if _channel_prompt else _history_block
    except Exception:
        pass
  1. No built-in channel history. When require_mention: true, the agent only sees the single @mention message — zero context about what other agents said. This makes collaborative workflows (code review, planning, critique) impossible without the patch above.

Code Example

# PATCH: inject recent channel history as context so agents can see
# each other's messages without needing to trigger each other.
# Controlled by DISCORD_CHANNEL_HISTORY_SIZE (0 = disabled).
_history_size = int(os.getenv("DISCORD_CHANNEL_HISTORY_SIZE", "0"))
if _history_size > 0:
    try:
        _history_lines = []
        async for _m in _chan.history(limit=_history_size, before=message):
            _author = _m.author.display_name or _m.author.name
            if _m.content:
                _history_lines.append(f"[{_author}]: {_m.content}")
        if _history_lines:
            _history_block = "Recent channel history (oldest to newest):\n" + "\n".join(reversed(_history_lines))
            _channel_prompt = (_history_block + "\n\n" + _channel_prompt).strip() if _channel_prompt else _history_block
    except Exception:
        pass

---

discord:
  require_mention: true
  free_response_channels: '<home_channel_id>'
  allowed_channels: '<home_channel_id>,<shared_channel_id>'
RAW_BUFFERClick to expand / collapse

Summary

We run a multi-agent Discord setup (3 specialized Hermes instances in separate systemd services, each with its own profile, persona, and model). The biggest pain point: agents in shared channels have no visibility into each other's messages, making collaborative workflows impossible without triggering response cascades.

We built a working solution and want to share the approach for potential upstreaming. Related to #13054 (which proposes the same history injection) but we also solved the cascade prevention and mention-gating problems that come with multi-bot shared channels.

Our Setup

  • 3 Hermes instances: Raiden (coder, GLM-5.1), Zhongli (architect, Kimi K2.6), Nahida (critic, Qwen 3.6 Plus)
  • Each runs as a separate systemd service with HERMES_HOME pointing to its own profile
  • Shared Discord channel where all three are present
  • A human @mentions one agent to kick off a task; agents should see full channel context but NOT respond unless mentioned

What We Built

1. Channel History Injection (same direction as #13054)

A small patch in _handle_message that fetches the last N messages from Discord channel history and prepends them to the channel prompt:

# PATCH: inject recent channel history as context so agents can see
# each other's messages without needing to trigger each other.
# Controlled by DISCORD_CHANNEL_HISTORY_SIZE (0 = disabled).
_history_size = int(os.getenv("DISCORD_CHANNEL_HISTORY_SIZE", "0"))
if _history_size > 0:
    try:
        _history_lines = []
        async for _m in _chan.history(limit=_history_size, before=message):
            _author = _m.author.display_name or _m.author.name
            if _m.content:
                _history_lines.append(f"[{_author}]: {_m.content}")
        if _history_lines:
            _history_block = "Recent channel history (oldest to newest):\n" + "\n".join(reversed(_history_lines))
            _channel_prompt = (_history_block + "\n\n" + _channel_prompt).strip() if _channel_prompt else _history_block
    except Exception:
        pass

Controlled by DISCORD_CHANNEL_HISTORY_SIZE env var (0 = off, we use 50).

2. Cascade Prevention

This was the hard part. With DISCORD_ALLOW_BOTS=all, all three agents saw every message and responded to each other in an infinite loop. The existing require_mention + DISCORD_ALLOW_BOTS interaction wasn't sufficient alone.

Our working configuration for each agent's systemd service:

VariableValueWhy
DISCORD_ALLOW_BOTSmentionsAgents only process bot messages where they're @mentioned
DISCORD_REQUIRE_MENTIONtrueAgents only respond when @mentioned by anyone
DISCORD_CHANNEL_HISTORY_SIZE50Context injection amount

Plus each agent's SOUL.md includes instructions to never use @ when referencing other agents by name (prevents accidental mention triggers from bot-generated text).

3. Per-Channel Behavior

Using free_response_channels to allow free response in an agent's "home" channel while requiring mentions in the shared multi-agent channel:

discord:
  require_mention: true
  free_response_channels: '<home_channel_id>'
  allowed_channels: '<home_channel_id>,<shared_channel_id>'

Pain Points Encountered

  1. require_mention config is fragile. It's set in config.yaml under discord:, which gets mapped to env var DISCORD_REQUIRE_MENTION at load time — but only if the env var isn't already set. We had to set the env var directly in the systemd service to guarantee it takes effect.

  2. DISCORD_ALLOW_BOTS values are poorly documented. The three modes (none, mentions, all) are critical for multi-agent but only discoverable by reading the source. The mentions mode is the correct choice for multi-agent but wasn't obvious.

  3. No built-in channel history. When require_mention: true, the agent only sees the single @mention message — zero context about what other agents said. This makes collaborative workflows (code review, planning, critique) impossible without the patch above.

  4. Bot-generated @mentions trigger loops. If agent A says "ask @Raiden for help", that's a Discord mention that triggers Raiden. We had to add SOUL.md instructions to prevent this, but it's fragile — a proper solution would be a gateway-level option to ignore bot-originated mentions.

Proposed Upstream Changes

We'd love to see these land natively:

  1. DISCORD_CHANNEL_HISTORY_SIZE env var (or history_backfill as #13054 proposes) — our patch above, or their PR. Either works.
  2. DISCORD_ALLOW_BOTS=mentions mode — already exists, just needs better documentation.
  3. A bot_mentions_trigger: false config — prevents bot-generated @mentions from triggering other bots, solving the cascade problem at the gateway level instead of relying on SOUL.md instructions.
  4. Multi-agent docs page — documenting the systemd profile pattern, env var combinations, and common pitfalls.

Happy to help test or refine any of these if there's interest.

extent analysis

TL;DR

To resolve the issue of agents in shared channels having no visibility into each other's messages and to prevent response cascades, apply the proposed patch for channel history injection and configure DISCORD_ALLOW_BOTS and DISCORD_REQUIRE_MENTION environment variables.

Guidance

  1. Apply the channel history injection patch: Modify the _handle_message function to fetch recent channel history and prepend it to the channel prompt, controlled by the DISCORD_CHANNEL_HISTORY_SIZE environment variable.
  2. Configure DISCORD_ALLOW_BOTS and DISCORD_REQUIRE_MENTION: Set DISCORD_ALLOW_BOTS to mentions and DISCORD_REQUIRE_MENTION to true to ensure agents only process bot messages where they're @mentioned and only respond when @mentioned.
  3. Use free_response_channels for per-channel behavior: Configure free_response_channels to allow free response in an agent's "home" channel while requiring mentions in the shared multi-agent channel.
  4. Prevent bot-generated @mentions from triggering loops: Add instructions to each agent's SOUL.md to never use @ when referencing other agents by name, or propose a gateway-level option to ignore bot-originated mentions.

Example

The provided patch for channel history injection can be applied as follows:

_history_size = int(os.getenv("DISCORD_CHANNEL_HISTORY_SIZE", "0"))
if _history_size > 0:
    # fetch recent channel history and prepend to channel prompt
    # ...

Notes

The proposed solution relies on the DISCORD_CHANNEL_HISTORY_SIZE environment variable, which may need to be adjusted based on the specific use case. Additionally, the SOUL.md instructions to prevent bot-generated @mentions from triggering loops may be fragile and require careful maintenance.

Recommendation

Apply the proposed workaround by configuring DISCORD_ALLOW_BOTS and DISCORD_REQUIRE_MENTION environment variables

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING