feat(mention-gating): suppress always-on agent when another agent is explicitly mentioned#67460
feat(mention-gating): suppress always-on agent when another agent is explicitly mentioned#67460MoeJaberr wants to merge 10 commits intoopenclaw:mainfrom
Conversation
…aversal After a global npm upgrade, older installs left dist/extensions/*/node_modules/ in place (npm does not remove dirs absent from the new tarball). These directories contained .bin/ symlinks that caused listInstalledDistFiles to throw "unsafe dist entry", aborting the postinstall before acpx could be installed at the package root. The acpx binary was then resolved from the stale nested path instead of node_modules/.bin/acpx at the package root, causing ACP launches to fail. Fix: call pruneBundledDistPluginNodeModules (mirroring the existing source-checkout pruneBundledPluginSourceNodeModules) before pruneInstalledPackageDist so the stale directories are removed before listInstalledDistFiles traverses dist/. Fixes openclaw#65921 Co-Authored-By: claude-flow <ruv@ruv.net>
…explicitly mentioned Implements the behavior described in openclaw#67445: when a channel has a default always-on agent (requireMention=false) and a message explicitly mentions a different agent, the always-on agent can now suppress itself instead of responding to every message. New opt-in policy field on InboundMentionPolicy: suppressIfOtherAgentMentioned?: boolean When true, resolveInboundMentionDecision() sets shouldSkip=true and the new suppressedByOtherAgentMention=true on the returned decision whenever: - isGroup=true (group chat only) - canDetectMention=true (platform supports mention detection) - hasAnyMention=true (some agent was mentioned) - wasMentioned=false (but not this agent) - requireMention=false (this is the always-on agent path) Untagged messages continue to reach the default agent unchanged. Opt-in design preserves backward compatibility for existing channels. Co-Authored-By: claude-flow <ruv@ruv.net>
Greptile SummaryThis PR adds an opt-in
Confidence Score: 4/5Safe to merge after fixing the silent field-drop in the deprecated flat-params normalization path. One P1 defect:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e3c767ba5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…at-params normalizer normalizeMentionDecisionParams was dropping the new field, causing the suppression to silently not fire when callers used the deprecated flat call shape. Destructure and forward it alongside the other policy fields. Adds a regression test covering the flat-params path. Co-Authored-By: claude-flow <ruv@ruv.net>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 50ba281e8b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ioned Wires up the new policy flag across all 11 channel extensions so that always-on agents (requireMention=false) automatically suppress themselves when a message explicitly mentions a different agent. Channels where hasAnyMention is reliably populated (Discord, Telegram, Slack, Line, Google Chat, Zalouser) get full suppression behavior. Channels without hasAnyMention detection (Signal, iMessage, MS Teams, Nextcloud Talk, WhatsApp) carry the flag harmlessly with no behavioral change until their mention-detection improves. Closes openclaw#67445. Co-Authored-By: claude-flow <ruv@ruv.net>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 441cdd71d4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The upstream commit 628b454 updated the default Anthropic model to claude-opus-4-7 but did not update the hardcoded constant in these test files, causing CI to fail on the merge commit. Co-Authored-By: claude-flow <ruv@ruv.net>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb9c6e76c7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
All CI checks are green (only |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba67a94f2d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
ba67a94 to
ede30ff
Compare
…guards Address Codex P1/P2 review findings on PR openclaw#67460: P1 — skip guard was gated behind requireMention=true so always-on agents never acted on mentionDecision.shouldSkip when suppression fired: - Telegram, Slack, Signal, WhatsApp, MS Teams: expand guard to also short-circuit when suppressedByOtherAgentMention is true. - Discord: add a dedicated early-return for the same case (the existing block is nested inside shouldRequireMention). P1 — hasAnyMention was not passed so suppression could never trigger: - Signal: compute from dataMessage.mentions.length - WhatsApp: compute from msg.mentions ?? msg.mentionedJids length - MS Teams: compute from activity.entities type=mention entries Co-Authored-By: claude-flow <ruv@ruv.net>
ede30ff to
6f93532
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6f93532af1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…preserving suppressIfOtherAgentMentioned
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6338a30ce8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ving policy.ts conflict
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc567e0275
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const pluginNodeModules = join(extensionsDir, entry.name, "node_modules"); | ||
| if (pathExists(pluginNodeModules)) { | ||
| removePath(pluginNodeModules, { recursive: true, force: true }); |
There was a problem hiding this comment.
Guard dist prune against symlinked extension roots
pruneBundledDistPluginNodeModules recursively deletes dist/extensions/*/node_modules without validating that extensionsDir is a real directory under the package root (unlike the resolveInstalledDistRoot checks used by pruneInstalledPackageDist). If dist/extensions is a symlink (or otherwise redirected), postinstall can remove node_modules outside the OpenClaw install tree, including during global installs run with elevated privileges. Add lstat/realpath boundary checks before calling rmSync.
Useful? React with 👍 / 👎.
| allowTextCommands: params.allowTextCommands, | ||
| hasControlCommand: params.hasControlCommand, | ||
| commandAuthorized: params.commandAuthorized, | ||
| suppressIfOtherAgentMentioned: true, |
There was a problem hiding this comment.
Pass any-mention facts before enabling Nextcloud suppression
resolveNextcloudTalkMentionGate now opts into suppressIfOtherAgentMentioned, but the inbound caller (extensions/nextcloud-talk/src/inbound.ts) still does not provide hasAnyMention, so it defaults false and suppressedByOtherAgentMention cannot trigger. In always-on rooms (requireMention=false), messages that explicitly mention a different agent will still be processed by the default agent, so this commit’s suppression behavior is effectively disabled for Nextcloud.
Useful? React with 👍 / 👎.
| allowTextCommands: true, | ||
| hasControlCommand: hasControlCommandInMessage, | ||
| commandAuthorized, | ||
| suppressIfOtherAgentMentioned: true, |
There was a problem hiding this comment.
Honor always-on suppression in iMessage mention gate
This handler enables suppressIfOtherAgentMentioned, but the drop path still requires requireMention before acting on mentionDecision.shouldSkip, so the new always-on suppression path (requireMention=false) is never applied. Because this function now opts into suppression, always-on iMessage groups can still respond when another agent is explicitly targeted, which defeats the new behavior on this channel.
Useful? React with 👍 / 👎.
…ges before placeholder hydration
|
All Codex review threads have been resolved. The Greptile P1 finding ( The branch is up to date with Tagging for review: @joshavant @gumadeiras — happy to address any feedback. 🙏 |
3a13a6a to
b67f403
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b67f403fa8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| author, | ||
| sender, | ||
| memberRoleIds, | ||
| channelInfo, |
There was a problem hiding this comment.
Restore member roles in Discord preflight return payload
This return object dropped memberRoleIds, but downstream processing still expects it: processDiscordMessage destructures memberRoleIds and forwards it into finalizeInboundContext as MemberRoleIds (extensions/discord/src/monitor/message-handler.process.ts). With this omission, inbound Discord messages lose sender role context at runtime, which can break role-scoped behavior (for example role-based command/policy decisions and prompt context). Add memberRoleIds back to the preflight context payload.
Useful? React with 👍 / 👎.
|
Codex review: found issues before merge. Summary Reproducibility: yes. Current-main behavior is reproducible by code inspection of Next step before merge Security Review findings
Review detailsBest possible solution: Land a narrower routing change or replacement branch that introduces a typed explicit-agent-target signal, wires only channels that can prove that signal, preserves Discord role context, separates postinstall cleanup into a security-reviewed patch, and adds focused shared plus channel regression coverage with a changelog entry. Do we have a high-confidence way to reproduce the issue? Yes. Current-main behavior is reproducible by code inspection of Is this the best way to solve the issue? No. The requested behavior belongs in the shared mention-policy area, but this implementation is not the best fix because it uses generic platform mention evidence as agent-target evidence and mixes unrelated install-script cleanup into a routing feature. Full review comments:
Overall correctness: patch is incorrect Security concerns:
Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 9e5d0380b0ec. |
Summary
suppressIfOtherAgentMentioned?: booleantoInboundMentionPolicysuppressedByOtherAgentMention: booleantoInboundMentionDecisiontrue, an always-on agent (requireMention=false) setsshouldSkip=trueif another agent was explicitly mentioned and this agent was notWhy
Closes #67445. In channels with a default auto-responding agent, any message that explicitly tags a different agent should reach only that agent — the default responder is noisy otherwise. The existing
hasAnyMention+wasMentionedsignals already carry the right information; this PR wires them into a new suppression path.Behavior
Design notes
suppressIfOtherAgentMentioneddefaults toundefined(off). Existing channels are unaffected until they set the flag.requireMention=trueagents already have their own skip path; this only applies whenrequireMention=false.suppressIfOtherAgentMentionedtoChannelGroupConfigso users can enable it from their config file without touching plugin code.Test plan
bunx vitest run src/channels/mention-gating.test.ts— 24/24 passbunx tsc --noEmit— no errors on touched files