feat(msteams): respond to channel messages by keyword without an @mention#92591
feat(msteams): respond to channel messages by keyword without an @mention#92591colton-octaria wants to merge 1 commit into
Conversation
|
Codex review: needs changes before merge. Reviewed June 30, 2026, 7:51 PM ET / 23:51 UTC. Summary PR surface: Source +59, Tests +51. Total +110 across 5 files. Reproducibility: yes. for the review blocker: source inspection shows the PR adds a Teams config key while generated metadata, UI hints, and docs omit it. The Teams runtime behavior itself has contributor-supplied live log proof rather than a reviewer-run live reproduction. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof path suggestion Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Land the shared Teams keyword-mention runtime seam only after Teams UI hints, generated channel metadata, public docs for Teams conversation IDs, and a current-main refresh are aligned. Do we have a high-confidence way to reproduce the issue? Yes for the review blocker: source inspection shows the PR adds a Teams config key while generated metadata, UI hints, and docs omit it. The Teams runtime behavior itself has contributor-supplied live log proof rather than a reviewer-run live reproduction. Is this the best way to solve the issue? No, not complete yet. Reusing the shared mention-pattern seam is the right owner boundary, but the best fix also updates the Teams config contract surfaces and refreshes the branch before merge. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 5e572dcf781a. Label changesLabel justifications:
Evidence reviewedPR surface: Source +59, Tests +51. Total +110 across 5 files. View PR surface stats
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
|
Context: this is a companion to #90738 (inbound channel file reading for msteams) — same effort to bring the Microsoft Teams channel up to parity with the other group-capable channels. #90738 fixes a bug in how channel messages are read; this PR adds the keyword-mention seam ( On the "is this the best fix?" question: the alternatives are worse. Flipping The two PRs are independent (different files: #90738 touches the Graph attachment-fetch path; this touches the config schema + the mention gate), so they can land in any order. |
|
@clawsweeper re-review The previous Codex run failed to execute (exit 1, and it reported it "could not read AGENTS.md completely") rather than evaluating the change, so the rating came back as off-meta tidepool. All GitHub CI checks are green — including Real behavior proof, build-artifacts, check-lint, check-prod-types, check-test-types, and the boundary/security/contract shards — so please retry the review against the actual diff. |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
…tion The MS Teams channel is the only group-capable channel that ignores messages.groupChat.mentionPatterns: Discord, Slack and WhatsApp all expose a per-provider mentionPatterns policy that scopes those patterns and treats a text match as an implicit mention, but msteams drops every non-@mention group message at the requireMention gate. This adds the same seam to msteams. - config: channels.msteams.mentionPatterns (MentionPatternsPolicyConfig), matching the discord/slack/whatsapp shape; scopes the global messages.groupChat.mentionPatterns to selected Teams conversations. - handler: build the mention regexes and OR a match into the wasMentioned fact fed to resolveInboundMentionDecision, so a named-without-@ message dispatches while non-matching messages still hit the requireMention skip (no extra model turn). Self-echo guarded so the bot does not trigger on its own posts (with RSC ChannelMessage.Read.Group the bot also receives its own channel messages). - isMSTeamsKeywordMention helper (mirrors discord's mention-state resolution), unit-tested for match/case-insensitive/no-keyword/self-echo/DM/already- mentioned/empty-patterns/empty-text.
e7707b6 to
763dd83
Compare
|
@clawsweeper re-review Rebased onto current |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Now rebased onto current main (head 763dd83 on 6cf06e8). The earlier post-rebase run was cancelled before completing. Please review against the current base. |
|
This pull request has been automatically marked as stale due to inactivity. |
Summary
The MS Teams channel is the only group-capable channel that ignores
messages.groupChat.mentionPatterns. Discord, Slack and WhatsApp each expose a per-providermentionPatternspolicy that scopes those patterns and treats a text match as an implicit mention — so a user can address the agent by name without an@. The msteams handler never wired this, so every non-@mentiongroup/channel message is dropped at therequireMentiongate.This adds the same seam to msteams (no new concept):
channels.msteams.mentionPatterns(MentionPatternsPolicyConfig), identical in shape tochannels.discord.mentionPatterns/ slack / whatsapp. It scopes the globalmessages.groupChat.mentionPatternsto selected Teams conversations (allow/deny by conversation id).buildMentionRegexes(cfg, agentId, { provider: "msteams", conversationId, providerPolicy: msteamsCfg?.mentionPatterns })) and OR a match into thewasMentionedfact passed toresolveInboundMentionDecision. A matched message dispatches as if@mentioned; everything else still hits the existingrequireMentionskip, so there is no extra model turn for ordinary channel chatter.requireMentionsemantics are unchanged.ChannelMessage.Read.Groupthe bot also receives its own channel posts; the newisMSTeamsKeywordMentionhelper returns false whenactivity.from.id === activity.recipient.id, so a reply that contains the keyword cannot re-trigger the bot.isMSTeamsKeywordMentioninextensions/msteams/src/mentions.ts(mirrors Discord's mention-state resolution), unit-tested.Config surface note
This adds one config field to an existing channel to reach parity with three sibling channels that already have it; the matching patterns still come from the existing global
messages.groupChat.mentionPatterns. No default changes, no migration, fully backward-compatible (absent → today's behavior exactly).Real behavior proof
Behavior addressed: A Microsoft Teams channel message that names the agent (matches a configured mention pattern, e.g.
\bradar\b) without an@mentionnow gets a reply; a channel message that does not match still gets no reply and triggers no model turn; the bot does not trigger on its own posts.Real environment tested: A live Microsoft Teams deployment (OpenClaw 2026.6.5, native msteams plugin) with the equivalent keyword-mention behavior applied to the installed plugin and
RSC ChannelMessage.Read.Groupconsented, exercised by posting real messages in a Teams channel and reading the bot's edge (nginx) and gateway journals over ssh.Exact steps or command run after this patch: Posted three top-level channel messages naming the agent without an
@("Radar, can you hear me now?", "RADAR ... who am i", "cool... radar... can you give me latest oil price") and one with no keyword ("The weather today in Little Rock, is sunny and quite nice."), then read the inbound edge and gateway activity:Evidence after fix: The inbound non-
@channel message reaches the bot, and only the keyword messages start an agent turn:Observed result after fix: All three keyword messages were answered in-channel without an
@mention; the no-keyword weather message was received by the bot but produced no agent turn and no reply (therequireMentionskip still fires for non-matches); the bot did not reply to its own keyword-containing replies.@mentionand DM behavior were unchanged.What was not tested: I exercised the behavior live via the equivalent keyword-mention logic applied to a deployed 2026.6.5 plugin rather than a from-source gateway build of this exact branch; the source on this branch is covered by the added
isMSTeamsKeywordMentionunit cases (match / case-insensitive / no-keyword / self-echo / DM / already-mentioned / empty-patterns / empty-text), which I ran green locally via the repo's scoped vitest helper. I could not run the full localpnpm checklanes (oxfmt / tsgo / broad suites) — the toolchain is not fully installed in my checkout. Private/shared-channel RSC variants were not exercised.Screenshots of the live Teams thread are available on request (repo policy keeps proof images off branches).