fix(chat): honor adapter-reported non-mentions - #946
Merged
Merged
Conversation
Signed-off-by: Hiroki Osame <hiroki.osame@gmail.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Signed-off-by: Hiroki Osame <hiroki.osame@gmail.com>
privatenumber
added this pull request to stack #948
September 16, 2026 11:41
Signed-off-by: Hiroki Osame <hiroki.osame@gmail.com>
Signed-off-by: Hiroki Osame <hiroki.osame@gmail.com>
- X: posts rebuilt from raw or fetched by id, and DMs, no longer report `isMention: false`; only `post.mention.create` events set `true` - Discord: webhook and gateway paths report `true` for a real ping, role mention, `@everyone`, or allowlisted channel, and leave the field unset otherwise - Notion: `keyword` mode returns `undefined` when no keyword matches or the keyword list is empty; `isMe` comments still report `false` - Linear: use an explicit `? true : undefined` ternary for agent session comments - chat: document that the DM backward-compat rule overrides the adapter's value when no `onDirectMessage` handler is registered - Docs: describe the three `isMention` states in the API reference, the adapter-building guide, and the Notion mention table; note the DM exception - Tests: X parseMessage and Notion keyword mode assert the field is undefined; Discord non-mention assertions updated to match - Changeset: bump `chat` as minor and add notion, x, and discord alongside linear Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com>
bensabic
approved these changes
Sep 17, 2026
bensabic
added a commit
that referenced
this pull request
Sep 17, 2026
## Summary - Code samples that contain the bot's id no longer start a conversation - Real mentions keep working, including beside a code sample - Depends on [#946](#946), which lets the adapter's non-mention decision stick ## Problem Chat SDK routes a message to `onNewMention` when the bot is mentioned, and the Slack adapter decided that from the raw text: it scanned for the bot's id and marked every `app_mention` event as a mention. Slack models those two cases differently. A [user mention](https://docs.slack.dev/reference/block-kit/block-elements/user-element/) "renders as a mention of a user", while a [text element](https://docs.slack.dev/reference/block-kit/block-elements/text-element/) with `style.code` displays literal code. Both can carry the same id characters: ```json { "type": "text", "text": "<@UBOT123>", "style": { "code": true } } ``` ```json { "type": "user", "user_id": "UBOT123" } ``` Only the second is a mention. Because the adapter also searched the text, a message that only documents the bot was treated as an invocation: 1. A user posts a code sample that contains the bot's id. 2. Slack delivers the event as `app_mention`. 3. The adapter set `isMention`, and the mention handler ran. ## Changes The adapter now classifies the content the way Slack renders it, instead of scanning every string for the bot's id. - A `user` element for the bot outside code is a mention. - A `<@U…>` token in a text object explicitly typed `mrkdwn` is a mention. - Inline code (`style.code`) and `preformatted` elements are not. - A rich-text `text` element, a link label, and a `raw_text` table cell are display text. A token there stays literal, so it is not a mention. When a message carries blocks, those blocks model its body and the flattened `text` field is not consulted, because it loses the code/literal distinction. Attachment blocks are authoritative for their attachment, so an attachment's legacy fallback cannot add mention evidence. Blocks and mrkdwn content are both traversed, so a `section` block mention is still found. The unconditional `app_mention` override is gone. A fully inspected message with no mention reports `isMention: false`, even when the bot's display name appears as plain text, which [#946](#946) preserves. If the adapter cannot identify the bot (`botUserId` unresolved), an `app_mention` event is still trusted and other messages stay undetermined. The routing test in [packages/adapter-slack/src/index.test.ts](https://github.com/vercel/chat/blob/b2d05aa2/packages/adapter-slack/src/index.test.ts) sends a signed webhook through the real adapter and a real `Chat` instance. Against the pre-fix adapter it fails because the mention handler runs; with the fix it passes. Seven cases were confirmed to fail before the element-type fix, covering `raw_text` cells, rich-text text elements, link labels, `plain_text` blocks, and attachment fallbacks. The Slack integration suite also delivered events as `text: "@botName ..."`. Slack mentions are `<@U…>` tokens, so those fixtures were corrected to the documented syntax; the operations those tests own (subscriptions, edits, reactions, uploads) are unchanged. Changed files: - [packages/adapter-slack/src/index.ts](https://github.com/vercel/chat/blob/b2d05aa2/packages/adapter-slack/src/index.ts): element-typed mention classification across rich text, tables, and attachments - [packages/adapter-slack/src/index.test.ts](https://github.com/vercel/chat/blob/b2d05aa2/packages/adapter-slack/src/index.test.ts): adapter-level classification and webhook-to-handler routing - [packages/integration-tests/src/slack.test.ts](https://github.com/vercel/chat/blob/b2d05aa2/packages/integration-tests/src/slack.test.ts): mention fixtures corrected to `<@U…>` syntax ## Related PRs - Depends on [#946](#946): without it, `Chat` re-detects the mention from the flattened text and the false positive returns --------- Signed-off-by: Hiroki Osame <hiroki.osame@gmail.com> Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
amitvijapur
added a commit
to amitvijapur/chat
that referenced
this pull request
Sep 20, 2026
…acket-snapshot Forwarding moved behind enqueueOrderedForward on main (vercel#946, vercel#927), which defers the task a microtask even on an empty queue, so the snapshot now happens in the raw handler before the enqueue and the clone is what gets forwarded.
patrick-chinchill
added a commit
to Chinchill-AI/chat-sdk-python
that referenced
this pull request
Oct 1, 2026
…termined comment mentions (#232) Linear agent sessions now route every event to one stable thread, linear:{issueId}:s:{agentSessionId}, instead of one :c:{comment}:s:{session} thread per source comment. Ports upstream 3d2cb22a (vercel/chat#885, chat@4.40.0): rootless sessions are dispatched with a synthetic root comment, creator-less sessions are authored by linear-automation, prompted events fall back to the activity id, and fetch pages agentSession.activities for sessions with no root comment. Ports the Linear half of fcdc1c9e (vercel/chat#946, chat@4.41.0): agent-session comments are is_mention=True, and ordinary comments leave is_mention unset so core @mention detection runs. Divergence: the activities query is raw GraphQL, checked against Linear's published schema (no Python @linear/sdk). Documented in docs/UPSTREAM_SYNC.md. Consumer impact: new agent-session events use the stable session thread id. Stored old :c:...:s:... ids still decode to the same session, so posting to them still works. Closes #232
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Chat SDK decides whether to call
onNewMentionfrommessage.isMention, and adapters are expected to set that flag from platform-specific content. Core then overrides a negative result:An adapter can inspect content that plain text cannot. Slack, for example, distinguishes a user mention from a code-styled text element, even when both contain the same characters.
With
||, that distinction is lost. An adapter that reportsisMention: falsefor a code sample is overridden when text detection finds@usernamein the flattened message, and the mention handler runs for a message that mentions nobody. #947 depends on this behavior: without it, the Slack adapter cannot keep literal code out of mention routing.Changes
message.isMentionis now a three-state value.truefalseundefined@usernamein the message textAn adapter that reads structured content reports
trueorfalse; one that needs text matching leaves the flag unset. The same rule applies to messages skipped while draining a queue. Ordinary Linear comments now leave the flag unset so@displayNamedetection in a comment body keeps working.Adapter authors that previously returned
falseto mean "not detected" should returnundefinedinstead. The adapter-building docs now state this contract, which the previous docs left implicit by only showing thetruecase.Changed files:
Related PRs