Skip to content

fix: require_mention falls through to default agent instead of dropping message#376

Merged
jamiepine merged 3 commits into
mainfrom
fix/require-mention-fallthrough
Mar 9, 2026
Merged

fix: require_mention falls through to default agent instead of dropping message#376
jamiepine merged 3 commits into
mainfrom
fix/require-mention-fallthrough

Conversation

@jamiepine

@jamiepine jamiepine commented Mar 9, 2026

Copy link
Copy Markdown
Member

Summary

  • require_mention has never worked — when a binding rejected a message due to missing mention, resolve_agent_for_message fell through to the default agent and processed it anyway
  • The check was also hardcoded to Discord only; Telegram, Slack, and Twitch silently ignored the setting

Changes

src/config/types.rs — Split matches() into matches_route() (routing criteria) and passes_require_mention() (mention filter). Made passes_require_mention platform-agnostic using each adapter's *_mentions_or_replies_to_bot metadata key. Changed resolve_agent_for_message to return Option<AgentId> — returns None when a binding matched on routing but was blocked by require_mention, so the message is dropped instead of falling through.

src/messaging/telegram.rs — Added telegram_mentions_or_replies_to_bot metadata key (Telegram was the only adapter missing a combined mention/reply flag). Checks both @botusername text mentions and reply-to-bot.

src/main.rs — Handle the None return with continue to drop suppressed messages.

Repro

With this config, the bot responds to every message in the bound channels despite require_mention = true:

[[bindings]]
agent_id = "spacedrive-discord"
channel = "discord"
channel_ids = ["1475586817456607353"]
guild_id = "949090953497567312"
require_mention = true

The binding rejects the message → falls through to default_agent_id ("main") → main processes it with no mention requirement.

Note

Fix Summary: This PR fixes the require_mention feature which was broken in two ways: mentioning only checks Discord and only as a routing filter, causing unmentioned messages to fall through to the default agent instead of being dropped. Now the check is platform-agnostic and properly suppresses messages before they reach fallback handling. Telegram adapter gains mention detection for the first time.

Written by Tembo for commit badee64. This will update automatically on new commits.

…ng message

Two bugs made require_mention completely non-functional:

1. When require_mention caused a binding to not match, resolve_agent_for_message
   fell through to the default agent, which processed the message anyway.
   Split matches() into matches_route() + passes_require_mention() and return
   None from resolve_agent_for_message when a binding matched on routing but
   was blocked by require_mention.

2. The require_mention check was hardcoded to Discord only. Made it
   platform-agnostic by checking each adapter's *_mentions_or_replies_to_bot
   metadata key. Added the missing telegram_mentions_or_replies_to_bot key
   to the Telegram adapter.
@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 99c35f30-56da-4829-89ec-c55b7100a909

📥 Commits

Reviewing files that changed from the base of the PR and between 5afbe63 and 3cd71b2.

📒 Files selected for processing (2)
  • src/config/types.rs
  • src/messaging/telegram.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/config/types.rs
  • src/messaging/telegram.rs

Walkthrough

Binding matching split into routing-only checks (matches_route) and a separate passes_require_mention filter; resolve_agent_for_message now returns Option<AgentId> and can suppress matches blocked by require_mention. Main loop handles the Option and drops suppressed messages. Telegram metadata now records combined mention-or-reply-to-bot state.

Changes

Cohort / File(s) Summary
Binding resolution refactor
src/config/types.rs
Renamed matchesmatches_route for routing checks; added private passes_require_mention(&self, message) enforcing require_mention (with DM exceptions); resolve_agent_for_message now returns Option<AgentId> and returns None when mention requirement blocks a route; updated comments.
Main loop update
src/main.rs
Adjusted inbound message handling to pattern-match the Option<AgentId> from resolve_agent_for_message, early-continue when None, and proceed using Some(agent_id).
Telegram metadata
src/messaging/telegram.rs
Added detection of telegram_mentions_or_replies_to_bot by combining text mention scanning and reply-to-bot matching; inserts the combined flag into message metadata.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary fix: require_mention was falling through to the default agent instead of dropping messages, which is the core issue addressed in the changeset.
Description check ✅ Passed The description is well-related to the changeset, clearly explaining the problem, solution, and affected files, with a concrete reproduction example and detailed explanation of the fix.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/require-mention-fallthrough

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread src/config/types.rs Outdated

// DMs are inherently directed at the bot — always pass.
let is_dm =
message.source == "discord" && !message.metadata.contains_key("discord_guild_id");

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.

contains_key("discord_guild_id") treats null as present, so a DM could get misclassified and blocked when require_mention is on. Safer to mirror the old as_u64().is_some() behavior.

Suggested change
message.source == "discord" && !message.metadata.contains_key("discord_guild_id");
let is_dm = message.source == "discord"
&& message
.metadata
.get("discord_guild_id")
.and_then(|v| v.as_u64())
.is_none();

Comment thread src/messaging/telegram.rs Outdated
// Matches the pattern used by Discord/Slack/Twitch adapters.
let mut mentions_or_replies_to_bot = false;

// Check text-based @mention (Telegram sends mentions as entities)

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.

Small nit: this comment says mentions come via entities, but the implementation is a case-insensitive substring search on extracted text/caption. Either parse entities, or tweak the comment to match what’s happening.

Suggested change
// Check text-based @mention (Telegram sends mentions as entities)
// Check text-based @mention in message text/caption.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/config/types.rs`:
- Around line 1541-1545: The DM-bypass only checks Discord; update the DM
detection to also recognize Telegram private chats so require_mention bindings
won't drop them: extend the is_dm condition (the variable named is_dm in this
code) to return true when message.source == "telegram" and message.metadata
contains telegram_chat_type == "private" (and/or when
telegram_mentions_or_replies_to_bot metadata is present/false for ordinary DM
text), then keep the existing early return; locate and modify the is_dm logic
that currently inspects message.source and message.metadata to include these
Telegram metadata keys.

In `@src/messaging/telegram.rs`:
- Around line 865-873: The code uses text_lower.contains(&mention) which allows
prefix matches like "@spacebot_extra"; instead, update the mention detection to
use Telegram entities or a username-boundary check: in the message handling
where you use bot_username, extract_text, and set mentions_or_replies_to_bot,
iterate message.entities (or parse MessageEntity entries) for
Mention/TextMention and compare the entity text (case-insensitive) to the exact
bot username, or if entities are not available, scan the text for occurrences of
"@{bot_username}" and ensure the character after the matched username is absent
or not in [A-Za-z0-9_] (and the char before is start or non-word) so you only
match whole Telegram usernames.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 294ac00c-b626-4e6a-8eee-b3044b3728bd

📥 Commits

Reviewing files that changed from the base of the PR and between a5eba12 and badee64.

📒 Files selected for processing (3)
  • src/config/types.rs
  • src/main.rs
  • src/messaging/telegram.rs

Comment thread src/config/types.rs
Comment thread src/messaging/telegram.rs Outdated
jamiepine and others added 2 commits March 9, 2026 09:17
- Fix discord_guild_id DM check: use .as_u64().is_none() instead of
  contains_key to handle null values correctly
- Add Telegram private chat DM bypass so require_mention doesn't
  drop direct messages on Telegram
- Fix Telegram mention prefix matching: add word-boundary check so
  @spacebot doesn't match @spacebot_extra
@jamiepine jamiepine merged commit 21ae608 into main Mar 9, 2026
4 checks passed
rktmeister pushed a commit to rktmeister/spacebot that referenced this pull request Mar 11, 2026
- Fix discord_guild_id DM check: use .as_u64().is_none() instead of
  contains_key to handle null values correctly
- Add Telegram private chat DM bypass so require_mention doesn't
  drop direct messages on Telegram
- Fix Telegram mention prefix matching: add word-boundary check so
  @spacebot doesn't match @spacebot_extra
rktmeister pushed a commit to rktmeister/spacebot that referenced this pull request Mar 11, 2026
…ention-fallthrough

fix: require_mention falls through to default agent instead of dropping message
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant