npm / @chat-adapter/slack
@chat-adapter/slack
What changed in @chat-adapter/slack 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
8 breaking4 security69 new APIs and options21 behavior and defaults36 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli init@chat-adapter/slack 4138 changes
Breaking changes 8
Mention classification now inspects message content and Slack rendering rather than relying on the app_mention event type; inspected messages without a mention report isMention: false.
Mentions and links in raw_text table cells render literally; a bot mention token no longer resolves to a display name.
Slack attachment downloads refuse private and internal addresses, cap responses at 25 MB, and time out after 30 seconds; the bot token is sent only to trusted Slack origins.
Card tables render as paginated, sortable data table blocks by default; header-only or over-limit tables retain their specified fallbacks.
Org-wide installs are keyed on enterprise_id instead of team_id across event, slash command, and interactive payload paths; internal StateAdapter installations may need repopulating under enterprise_id.
A configured webhookVerifier takes precedence over signingSecret and SLACK_SIGNING_SECRET.
The previous boolean is replaced by
channelVisibility.Adapter and StateAdapter implementations must now provide channelIdFromThreadId.
Security 4
External request targets are validated before credentials, message content, or attachment requests are sent.
Bounds the length of bracketed URLs parsed in the link-unfurl fallback to avoid quadratic scans on adversarial input; valid links are unaffected.
Scopes profile caching and display-name mention reverse indexing by installation in multi-workspace deployments, preventing profiles and mention resolutions from leaking across workspaces.
A security bypass involving url_verification was fixed.
New APIs and options 69
Adds an optional hook to namespace dedupe, lock, queue, and turn keys, isolating Slack message concurrency and turn cancellation by installation. In multi-workspace mode, upgrade chat and @chat-adapter/slack together and restart all workers; old queued keys are not migrated and…
Returns every message ID in order when a long reply rotates into several messages; the last entry in messageIds is id.
Adds Block Kit blocks to the message sharing uploaded files. Passing both blocks and initialComment throws a TypeError because Slack would silently ignore blocks.
Button and LinkButton accept user IDs allowed to see the button; Slack renders them as visible_to_user_ids, while other adapters show the button to everyone. Action handlers must still check who clicked.
Select and RadioSelect inputs in Slack modals can opt in to selection change events.
Adapter-scoped transport options support egress proxies across Socket Mode, response URLs, webhook forwarding, and guarded file downloads.
An opt-in webhook option propagates message, action, and slash command handler errors through waitUntil while preserving default behavior.
Sets the maximum age of a native Slack stream segment; after the default four minutes, the adapter continues the reply in a new message at the next paragraph break.
Adds lifecycle support, automatic session titles, and session stop/title-change events while preserving the legacy assistant_view compatibility path.
Provides native stop cancellation for Slack Agent Sessions.
SlackEvent.blocks is now typed with the exported SlackMessageBlock interface.
Adds lifecycle callbacks and dispatch support for Slack message_changed and message_deleted events.
Adds DateInput as a modal child; the Slack adapter renders it as a datepicker, and its submitted value arrives in event.values as a string.
Adds NumberInput as a modal child; the Slack adapter renders it as a number_input, and its submitted value arrives in event.values as a string.
Adds an optional isSystem field to distinguish platform-generated messages from humans and bots; Slack sets it for messages authored by its reserved USLACK user.
Normalized incoming Slack message authors expose email addresses through message.author.email when the users:read.email scope is available; otherwise the field is undefined.
Installation records now include enterpriseId and isEnterpriseInstall to represent org-wide installs.
Accepts an optional installationId so proactive or cron posts outside webhook handling can scope profile and mention caches.
Enables Slack Agent messaging behavior, including app_context_changed routing and folded context on DM messages.
The Slack adapter routes Slack's app_context_changed event.
Adds folded active-view context to the event so handlers can identify the view associated with an app-home open.
Adds the opened Slack tab to the event, distinguishing a Home-tab open from the DM-open signal under agent_view.
Adds a helper for attaching the feedback buttons block to non-streamed messages.
Adds chart elements and a Chart builder with JSX support for pie, bar, area, and line charts.
Adds a helper that renders chart data as a text table on platforms without native chart support.
The blocks subpath gains chart types and card children, data table rendering, and matching Slack limits.
Adds optional native thumbs-up/down feedback buttons to streamed replies, with clicks dispatched through bot.onAction.
Adds a helper for reading folded app context from DM messages.
Adds default rotating status strings for the assistant thinking indicator when no explicit status or messages are passed.
Adds a native streaming configuration option, enabled by default; disable it on Slack flavours without the chat.startStream family.
Adds a core event with normalized AppContextEntity[] describing the user's active view.
Accepts an optional thread reference so prompts can sit at the top of an agent conversation.
Adds static or per-thread prompts applied automatically when an assistant or agent thread opens; null or undefined skips a thread.
Adds an optional accessible table description.
Adds an optional field for specifying rows per page.
Adds support for stable IDs to link button action handlers.
Adds webClientOptions to SlackAdapterConfig and forwards it to default and per-token WebClient instances, exposing settings such as retryConfig, per-request timeout, and rejectRateLimitedCalls.
Exposes runtime-free helpers for converting Slack cards to Block Kit.
Adds helpers for files, thread replies, views, interactions, and input blocks.
Adds a lightweight subpath for Slack API primitives.
Adds a lightweight subpath for Slack formatting primitives.
Adds a lightweight subpath for Slack webhook primitives.
Expose typed WebClient access bound to the current request-context token or configured default token, enabling Web API calls not covered by high-level SDK methods.
The typed native Slack client getter is renamed from client to webClient to match the underlying SDK class; client remains as a deprecated alias.
Optionally resolve bot tokens for incoming events, slash commands, and interactive payloads through an external read-only provider instead of internal StateAdapter state.
Slack AdapterConfig types and related sub-types move into a ./types module; public re-exports from index.ts remain unchanged.
Allows passing redirectUri explicitly during the Slack OAuth token exchange, with the callback query parameter retained as a backward-compatible fallback.
Adds an enum to distinguish private, workspace, external, and unknown channel scopes.
Adds
getChannelVisibility()to the Adapter interface and Slack adapter.Introduces a LinkPreview object on Message.
Adds an API for transforming history to AI SDK messages.
EphemeralMessage is now generic over TRawMessage, allowing its raw message type to be specified.
Adds scheduling messages for a future time through Slack’s chat.scheduleMessage API, with cancellation support and the ScheduledMessage type.
Adds support for native Slack tables.
Adds onMemberJoinedChannel to the Slack adapter.
Adds the CardLink element.
You can now attach multiple files to the same Slack message instead of breaking by file.
Slack installations can use a custom key prefix.
The Slack adapter adds typing indicators using the Slack assistants API.
The adapter routes assistant_thread_context_changed events.
The adapter routes assistant_thread_started events.
Adds handler registration for assistant_thread_context_changed events.
Adds handler registration for assistant_thread_started events.
Adds a Slack adapter method to set assistant status.
Adds a Slack adapter method to set the assistant title.
Adds a Slack adapter method to set suggested prompts.
stream() accepts stopBlocks for Block Kit on stream finalization.
Adds support for slash commands in the Slack adapter.
Cards can now include inline Select components and Radio buttons.
Behavior and default changes 21
Post-and-edit fallback updates use Slack’s markdown_text field while streaming, so live-updating messages render markdown and have a 12,000-character ceiling instead of 4,000.
Custom status text is surfaced in the Agent messaging experience; clearing the status transitions the session to active.
Bot-authored messages use the Slack bot user ID when a bot profile is available.
Normalized Slack messages now include alert attachment content, so mention detection and onMessage pattern handlers can see alert text.
Channel-addressed calls echo context_team_id back as client_context_team_id when an event comes from a shared channel hosted on an away workspace.
Uses a 24-hour state-adapter marker to drop retried event deliveries after the original was dispatched, while still recovering retries whose first delivery never arrived.
Environment credential fallback is disabled only by explicitly supplied auth or verification fields, so unrelated config such as agentView does not suppress it.
Under agentView, Messages-tab DM messages are threaded with each user message as a root; subscribed openDM conversation threads continue receiving top-level DM messages.
Surfaces Slack's per-block validation details when block submission fails with invalid_blocks.
Card charts render as data visualization blocks and fall back to text when they violate Slack constraints.
Falls back to throttled post-and-edit if the first native streaming call is rejected, preserving consumed text; permanent platform errors disable native streaming for later streams on the adapter instance.
Makes file upload confirmation ids available in postMessage results.
Adapter internals are protected rather than private, allowing consumers to subclass adapters and override or extend their behavior.
The factory accepts SlackAdapterConfig directly instead of Partial<SlackAdapterConfig>; all config fields were already optional, so call sites need no changes.
Slack native streaming can send markdown tables without code fences; other consumers retain the append-only table fallback.
The adapter now depends on chat as a full dependency rather than an optional dependency.
Slack channel names are now resolved automatically.
Adapters have improved fallback-render behavior.
Markdown rendering is fully streaming, including for Slack, which has native streaming.
Markdown tables are rendered by the adapters.
Environment variables are now loaded automatically.
Fixes and other changes 36
Cuts Slack card text that exceeds Block Kit length limits, preventing Slack from rejecting messages. Markdown cuts preserve mentions, links, HTML entities, open code fences, and closing bold markers.
Backward thread history reads follow every API page before selecting the newest messages, fixing older replies being returned for threads spanning multiple pages. Long threads take one API call per page.
Preserves literal text and code formatting in incoming Slack messages and correctly parses email and phone links.
Completes open task cards when a stream segment rotates and replays in-progress cards in the next segment. Retired segments finish without Slack's error indicator; if closing cards are rejected, the adapter finalizes without them and streams the rest as text…
Inbound Slack messages convert special mentions and user group mentions to readable text.
Incoming bot mentions resolve to the bot’s display name in message text, while isMention is detected from the raw event text.
Receiving an empty status reactivates Slack Agent Sessions.
Preserves the first line of incoming Slack code blocks and treats only paired triple-backtick fences as code blocks, preventing formatting rewrites from altering fenced content.
Pasted Slack tables are preserved as structured table nodes in message.formatted and tab-separated text in message.text, with cell formatting and table order retained.
Normalizes the commonly hallucinated link order before Markdown conversion.
Preserves the Slack channel ID when converting labeled channel tokens, allowing agents to pass the ID to channel tools.
Resolves @name mentions on the native streaming path, matching the post-and-edit fallback while keeping fenced code literal and preserving existing ambiguity semantics.
Event token resolution prefers the envelope's authorizations[0] installation identity over top-level team_id or enterprise_id, which remain fallbacks.
Returns a replyable Slack thread ID by using the posted top-level message's timestamp as the thread root.
Recognizes bare @W… mentions in outgoing messages as raw Enterprise Grid user IDs so they render as real mentions instead of display names.
Handles org-wide Slack installs by keying the installation by enterprise ID instead of failing when Slack returns team: null; the result includes enterpriseId and isEnterpriseInstall.
Resolves per-installation tokens for events, slash commands, and interactive payloads in multi-workspace deployments, and preserves enterprise_id, is_enterprise_install, and is_ext_shared_channel in event payloads.
API calls while handling org-wide install events pass the event's team_id explicitly for workspace-scoped methods that require it.
Retry envelopes are now routed like first deliveries instead of being acknowledged and dropped; message-id deduplication drops true duplicates.
Cached Slack display names inside URLs are no longer resolved as user mentions before payload formatting.
Mention linking skips inline code spans and fenced code blocks, preventing handles in package names or shell snippets from becoming Slack user mentions.
Mention linking now skips whole http(s):// spans and excludes a slash immediately before @, preserving handles inside URLs while leaving whitespace- and punctuation-led mentions, emails, and mailto links unaffected.
Passes the Slack bot token through native stream append and stop calls.
Slack reaction events now resolve the reacting user's display name and real name through cached user lookup, falling back to the Slack user ID if lookup fails.
The factory no longer silently drops the apiUrl config field.
Fixes conversion of markdown tables to Slack table blocks.
Empty table cells now fall back to a single space to meet Slack Block Kit requirements and avoid
invalid_blockserrors.Duplicate mentions are resolved using the replace callback offset instead of indexOf.
The user cache is invalidated on Slack user_change events so display name updates are picked up immediately.
Reaction events on threaded replies now resolve the parent thread_ts, so onReaction receives the correct thread ID.
Compatibility fixes for AI SDK6.
Slack file_share messages are no longer silently dropped, allowing file uploads to reach processMessage.
The hasText check no longer causes a no_text error for file-only posts.
Nested lists are rendered with platform-appropriate indentation and ordered child content instead of being flattened.
The StreamChunk type now uses a discriminated union for improved type safety.
Standard Markdown bold in CardText content is converted to Slack and Google Chat formatting instead of rendering literally.