chat 4.29.0 → 4.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +31 -5
  2. package/dist/adapters/index.d.ts +594 -0
  3. package/dist/adapters/index.js +751 -0
  4. package/dist/ai/index.d.ts +3 -3
  5. package/dist/{chat-D9UYaaNO.d.ts → chat-BjhJs_sP.d.ts} +10 -8
  6. package/dist/{chunk-V25FKIIL.js → chunk-LNXHNIFE.js} +2 -0
  7. package/dist/index.d.ts +4 -4
  8. package/dist/index.js +15 -10
  9. package/dist/{jsx-runtime-CFq1K_Ve.d.ts → jsx-runtime-CzthIo1o.d.ts} +6 -1
  10. package/dist/jsx-runtime.d.ts +1 -1
  11. package/dist/jsx-runtime.js +1 -1
  12. package/docs/adapters.mdx +140 -127
  13. package/docs/ai/index.mdx +6 -0
  14. package/docs/api/cards.mdx +8 -1
  15. package/docs/api/message.mdx +5 -1
  16. package/docs/cards.mdx +9 -1
  17. package/docs/concurrency.mdx +1 -1
  18. package/docs/contributing/building.mdx +6 -0
  19. package/docs/conversation-history.mdx +1 -1
  20. package/docs/create-chat-sdk.mdx +143 -0
  21. package/docs/error-handling.mdx +1 -1
  22. package/docs/getting-started.mdx +7 -3
  23. package/docs/index.mdx +3 -1
  24. package/docs/meta.json +5 -1
  25. package/docs/platform-adapters.mdx +148 -0
  26. package/docs/slack-primitives.mdx +320 -0
  27. package/docs/slash-commands.mdx +6 -1
  28. package/docs/streaming.mdx +1 -1
  29. package/docs/teams-primitives.mdx +255 -0
  30. package/docs/testing.mdx +1 -1
  31. package/docs/threads-messages-channels.mdx +2 -2
  32. package/docs/usage.mdx +3 -3
  33. package/package.json +24 -5
  34. package/resources/guides/create-a-discord-support-bot-with-nuxt-and-redis.md +5 -1
  35. package/resources/guides/how-to-build-a-slack-bot-with-next-js-and-redis.md +5 -1
  36. package/resources/guides/human-in-the-loop-with-chat-sdk-and-workflow-sdk.md +176 -0
  37. package/resources/guides/liveblocks-chat-sdk-ai-sdk.md +165 -0
  38. package/resources/guides/run-and-track-deploys-from-slack.md +7 -5
  39. package/resources/guides/ship-a-github-code-review-bot-with-hono-and-redis.md +5 -1
  40. package/resources/guides/slack-bot-vercel-blob.md +254 -0
  41. package/resources/guides/triage-form-submissions-with-chat-sdk.md +3 -1
  42. package/resources/templates.json +5 -0
  43. /package/docs/{state.mdx → state-adapters.mdx} +0 -0
@@ -1,10 +1,10 @@
1
- import { r as Chat, R as ChannelVisibility } from '../chat-D9UYaaNO.js';
2
- export { g as AiAssistantMessage, h as AiFilePart, i as AiImagePart, j as AiMessage, k as AiMessagePart, l as AiTextPart, m as AiUserMessage, n as ToAiMessagesOptions, t as toAiMessages } from '../chat-D9UYaaNO.js';
1
+ import { x as Chat, w as ChannelVisibility } from '../chat-BjhJs_sP.js';
2
+ export { d as AiAssistantMessage, e as AiFilePart, f as AiImagePart, g as AiMessage, h as AiMessagePart, i as AiTextPart, j as AiUserMessage, aZ as ToAiMessagesOptions, b7 as toAiMessages } from '../chat-BjhJs_sP.js';
3
3
  import * as ai from 'ai';
4
4
  import { Tool } from 'ai';
5
5
  import '@workflow/serde';
6
6
  import 'mdast';
7
- import '../jsx-runtime-CFq1K_Ve.js';
7
+ import '../jsx-runtime-CzthIo1o.js';
8
8
 
9
9
  /**
10
10
  * The Chat instance used by all tools to dispatch operations.
@@ -1,6 +1,6 @@
1
1
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
2
2
  import { Root } from 'mdast';
3
- import { Z as ChatElement, C as CardElement, ac as ModalElement, ah as SelectOptionElement } from './jsx-runtime-CFq1K_Ve.js';
3
+ import { n as ChatElement, g as CardElement, Q as ModalElement, $ as SelectOptionElement } from './jsx-runtime-CzthIo1o.js';
4
4
 
5
5
  interface ThreadHistoryConfig {
6
6
  /** Maximum messages to keep per thread (default: 100) */
@@ -761,7 +761,9 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
761
761
  * Stream a message using platform-native streaming APIs.
762
762
  *
763
763
  * The adapter consumes the async iterable and handles the entire streaming lifecycle.
764
- * Only available on platforms with native streaming support (e.g., Slack).
764
+ * Available on platforms with native streaming or preview APIs.
765
+ * Adapters may return `null` before consuming any chunks to delegate back to
766
+ * Chat SDK's built-in post+edit fallback for the current thread.
765
767
  *
766
768
  * The stream can yield plain strings (text chunks) or {@link StreamChunk} objects
767
769
  * for rich content like task progress cards. Adapters that don't support structured
@@ -770,9 +772,9 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
770
772
  * @param threadId - The thread to stream to
771
773
  * @param textStream - Async iterable of text chunks or structured StreamChunk objects
772
774
  * @param options - Platform-specific streaming options
773
- * @returns The raw message after streaming completes
775
+ * @returns The raw message after streaming completes, or `null` to use core fallback
774
776
  */
775
- stream?(threadId: string, textStream: AsyncIterable<string | StreamChunk>, options?: StreamOptions): Promise<RawMessage<TRawMessage>>;
777
+ stream?(threadId: string, textStream: AsyncIterable<string | StreamChunk>, options?: StreamOptions): Promise<RawMessage<TRawMessage> | null>;
776
778
  /** Bot username (can override global userName) */
777
779
  readonly userName: string;
778
780
  }
@@ -1221,8 +1223,8 @@ interface Thread<TState = Record<string, unknown>, TRawMessage = unknown> extend
1221
1223
  * Post a message to this thread.
1222
1224
  *
1223
1225
  * Supports text, markdown, cards, and streaming from async iterables.
1224
- * When posting a stream (e.g., from AI SDK), uses platform-native streaming
1225
- * APIs when available (Slack), or falls back to post + edit with throttling.
1226
+ * When posting a stream (e.g., from AI SDK), uses adapter-native streaming
1227
+ * when available, or falls back to post + edit with throttling.
1226
1228
  *
1227
1229
  * @param message - String, PostableMessage, JSX Card, or AsyncIterable<string>
1228
1230
  * @returns A SentMessage with methods to edit, delete, or add reactions
@@ -1456,7 +1458,7 @@ interface Author {
1456
1458
  fullName: string;
1457
1459
  /** Whether the author is a bot */
1458
1460
  isBot: boolean | "unknown";
1459
- /** Whether the author is this bot */
1461
+ /** Whether this message was sent by this bot/runtime */
1460
1462
  isMe: boolean;
1461
1463
  /** Unique user ID */
1462
1464
  userId: string;
@@ -3153,4 +3155,4 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
3153
3155
  private runHandlers;
3154
3156
  }
3155
3157
 
3156
- export { type DirectMessageHandler as $, type Adapter as A, type AppendInput as B, type CustomEmojiMap as C, type AppendOptions as D, type EmojiMapConfig as E, type AppHomeOpenedEvent as F, type AppHomeOpenedHandler as G, type AssistantContextChangedEvent as H, type AssistantContextChangedHandler as I, type AssistantThreadStartedEvent as J, type AssistantThreadStartedHandler as K, type Attachment as L, Message as M, type Author as N, type Channel as O, type PostableObject as P, type ChannelInfo as Q, type ChannelVisibility as R, type StreamChunk as S, ThreadHistoryCache as T, type ChatConfig as U, type ChatInstance as V, type WellKnownEmoji as W, type ConcurrencyConfig as X, type ConcurrencyStrategy as Y, type CountQuery as Z, type DeleteTarget as _, type PostableObjectContext as a, type ThreadSummary as a$, type DurationString as a0, type Emoji as a1, type EphemeralMessage as a2, type FetchDirection as a3, type FetchOptions as a4, type FetchResult as a5, type FileUpload as a6, type FormattedContent as a7, type IdentityContext as a8, type IdentityResolver as a9, type ModalUpdateResponse as aA, type OptionsLoadEvent as aB, type OptionsLoadGroup as aC, type OptionsLoadHandler as aD, type OptionsLoadResult as aE, type PlanUpdateChunk as aF, type Postable as aG, type PostableAst as aH, type PostableCard as aI, type PostableMarkdown as aJ, type PostableMessage as aK, type PostableRaw as aL, type PostEphemeralOptions as aM, type QueueEntry as aN, type RawMessage as aO, type ReactionEvent as aP, type ReactionHandler as aQ, type ScheduledMessage as aR, type SentMessage as aS, type SlashCommandEvent as aT, type SlashCommandHandler as aU, type StateAdapter as aV, type StreamOptions as aW, type SubscribedMessageHandler as aX, type TaskUpdateChunk as aY, type Thread as aZ, type ThreadInfo as a_, type LinkPreview as aa, type ListQuery as ab, type ListThreadsOptions as ac, type ListThreadsResult as ad, type Lock as ae, type LockScope as af, type LockScopeContext as ag, type Logger as ah, type LogLevel as ai, type MarkdownTextChunk as aj, type MemberJoinedChannelEvent as ak, type MemberJoinedChannelHandler as al, type MentionHandler as am, type MessageContext as an, type MessageHandler as ao, type MessageMetadata as ap, type MessageSubject as aq, type ModalClearResponse as ar, type ModalCloseEvent as as, type ModalCloseHandler as at, type ModalCloseResponse as au, type ModalErrorsResponse as av, type ModalPushResponse as aw, type ModalResponse as ax, type ModalSubmitEvent as ay, type ModalSubmitHandler as az, type ThreadHistoryConfig as b, type TranscriptEntry as b0, type TranscriptRole as b1, type TranscriptsApi as b2, type TranscriptsConfig as b3, type UserInfo as b4, type WebhookOptions as b5, ConsoleLogger as b6, THREAD_STATE_TTL_MS as b7, type StreamEvent as c, type EmojiValue as d, type EmojiFormats as e, type AdapterPostableMessage as f, type AiAssistantMessage as g, type AiFilePart as h, type AiImagePart as i, type AiMessage as j, type AiMessagePart as k, type AiTextPart as l, type AiUserMessage as m, type ToAiMessagesOptions as n, ChannelImpl as o, deriveChannelId as p, type SerializedChannel as q, Chat as r, type MessageData as s, toAiMessages as t, type SerializedMessage as u, isPostableObject as v, type SerializedThread as w, ThreadImpl as x, type ActionEvent as y, type ActionHandler as z };
3158
+ export { type LockScope as $, type ActionEvent as A, type ConcurrencyConfig as B, type Channel as C, type ConcurrencyStrategy as D, ConsoleLogger as E, type CountQuery as F, type CustomEmojiMap as G, type DeleteTarget as H, type DirectMessageHandler as I, type DurationString as J, type Emoji as K, type EmojiFormats as L, type EmojiMapConfig as M, type EmojiValue as N, type EphemeralMessage as O, type FetchDirection as P, type FetchOptions as Q, type FetchResult as R, type FileUpload as S, type FormattedContent as T, type IdentityContext as U, type IdentityResolver as V, type LinkPreview as W, type ListQuery as X, type ListThreadsOptions as Y, type ListThreadsResult as Z, type Lock as _, type ActionHandler as a, type TranscriptRole as a$, type LockScopeContext as a0, type LogLevel as a1, type Logger as a2, type MarkdownTextChunk as a3, type MemberJoinedChannelEvent as a4, type MemberJoinedChannelHandler as a5, type MentionHandler as a6, Message as a7, type MessageContext as a8, type MessageData as a9, type PostableRaw as aA, type QueueEntry as aB, type RawMessage as aC, type ReactionEvent as aD, type ReactionHandler as aE, type ScheduledMessage as aF, type SentMessage as aG, type SerializedChannel as aH, type SerializedMessage as aI, type SerializedThread as aJ, type SlashCommandEvent as aK, type SlashCommandHandler as aL, type StateAdapter as aM, type StreamChunk as aN, type StreamEvent as aO, type StreamOptions as aP, type SubscribedMessageHandler as aQ, THREAD_STATE_TTL_MS as aR, type TaskUpdateChunk as aS, type Thread as aT, ThreadHistoryCache as aU, type ThreadHistoryConfig as aV, ThreadImpl as aW, type ThreadInfo as aX, type ThreadSummary as aY, type ToAiMessagesOptions as aZ, type TranscriptEntry as a_, type MessageHandler as aa, type MessageMetadata as ab, type MessageSubject as ac, type ModalClearResponse as ad, type ModalCloseEvent as ae, type ModalCloseHandler as af, type ModalCloseResponse as ag, type ModalErrorsResponse as ah, type ModalPushResponse as ai, type ModalResponse as aj, type ModalSubmitEvent as ak, type ModalSubmitHandler as al, type ModalUpdateResponse as am, type OptionsLoadEvent as an, type OptionsLoadGroup as ao, type OptionsLoadHandler as ap, type OptionsLoadResult as aq, type PlanUpdateChunk as ar, type PostEphemeralOptions as as, type Postable as at, type PostableAst as au, type PostableCard as av, type PostableMarkdown as aw, type PostableMessage as ax, type PostableObject as ay, type PostableObjectContext as az, type Adapter as b, type TranscriptsApi as b0, type TranscriptsConfig as b1, type UserInfo as b2, type WebhookOptions as b3, type WellKnownEmoji as b4, deriveChannelId as b5, isPostableObject as b6, toAiMessages as b7, type AdapterPostableMessage as c, type AiAssistantMessage as d, type AiFilePart as e, type AiImagePart as f, type AiMessage as g, type AiMessagePart as h, type AiTextPart as i, type AiUserMessage as j, type AppHomeOpenedEvent as k, type AppHomeOpenedHandler as l, type AppendInput as m, type AppendOptions as n, type AssistantContextChangedEvent as o, type AssistantContextChangedHandler as p, type AssistantThreadStartedEvent as q, type AssistantThreadStartedHandler as r, type Attachment as s, type Author as t, ChannelImpl as u, type ChannelInfo as v, type ChannelVisibility as w, Chat as x, type ChatConfig as y, type ChatInstance as z };
@@ -361,6 +361,7 @@ function Button(options) {
361
361
  function LinkButton(options) {
362
362
  return {
363
363
  type: "link-button",
364
+ id: options.id,
364
365
  url: options.url,
365
366
  label: options.label,
366
367
  style: options.style
@@ -893,6 +894,7 @@ function resolveJSXElement(element) {
893
894
  }
894
895
  const label = processedChildren.length > 0 ? processedChildren.map(String).join("") : props.label ?? "";
895
896
  return LinkButton({
897
+ id: props.id,
896
898
  url: props.url,
897
899
  label,
898
900
  style: props.style
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { P as PostableObject, A as Adapter, a as PostableObjectContext, S as StreamChunk, T as ThreadHistoryCache, b as ThreadHistoryConfig, c as StreamEvent, E as EmojiMapConfig, d as EmojiValue, W as WellKnownEmoji, e as EmojiFormats, C as CustomEmojiMap, f as AdapterPostableMessage } from './chat-D9UYaaNO.js';
2
- export { y as ActionEvent, z as ActionHandler, g as AiAssistantMessage, h as AiFilePart, i as AiImagePart, j as AiMessage, k as AiMessagePart, l as AiTextPart, m as AiUserMessage, F as AppHomeOpenedEvent, G as AppHomeOpenedHandler, B as AppendInput, D as AppendOptions, H as AssistantContextChangedEvent, I as AssistantContextChangedHandler, J as AssistantThreadStartedEvent, K as AssistantThreadStartedHandler, L as Attachment, N as Author, O as Channel, o as ChannelImpl, Q as ChannelInfo, R as ChannelVisibility, r as Chat, U as ChatConfig, V as ChatInstance, X as ConcurrencyConfig, Y as ConcurrencyStrategy, b6 as ConsoleLogger, Z as CountQuery, _ as DeleteTarget, $ as DirectMessageHandler, a0 as DurationString, a1 as Emoji, a2 as EphemeralMessage, a3 as FetchDirection, a4 as FetchOptions, a5 as FetchResult, a6 as FileUpload, a7 as FormattedContent, a8 as IdentityContext, a9 as IdentityResolver, aa as LinkPreview, ab as ListQuery, ac as ListThreadsOptions, ad as ListThreadsResult, ae as Lock, af as LockScope, ag as LockScopeContext, ai as LogLevel, ah as Logger, aj as MarkdownTextChunk, ak as MemberJoinedChannelEvent, al as MemberJoinedChannelHandler, am as MentionHandler, M as Message, an as MessageContext, s as MessageData, ao as MessageHandler, ap as MessageMetadata, aq as MessageSubject, ar as ModalClearResponse, as as ModalCloseEvent, at as ModalCloseHandler, au as ModalCloseResponse, av as ModalErrorsResponse, aw as ModalPushResponse, ax as ModalResponse, ay as ModalSubmitEvent, az as ModalSubmitHandler, aA as ModalUpdateResponse, aB as OptionsLoadEvent, aC as OptionsLoadGroup, aD as OptionsLoadHandler, aE as OptionsLoadResult, aF as PlanUpdateChunk, aM as PostEphemeralOptions, aG as Postable, aH as PostableAst, aI as PostableCard, aJ as PostableMarkdown, aK as PostableMessage, aL as PostableRaw, aN as QueueEntry, aO as RawMessage, aP as ReactionEvent, aQ as ReactionHandler, aR as ScheduledMessage, aS as SentMessage, q as SerializedChannel, u as SerializedMessage, w as SerializedThread, aT as SlashCommandEvent, aU as SlashCommandHandler, aV as StateAdapter, aW as StreamOptions, aX as SubscribedMessageHandler, b7 as THREAD_STATE_TTL_MS, aY as TaskUpdateChunk, aZ as Thread, x as ThreadImpl, a_ as ThreadInfo, a$ as ThreadSummary, n as ToAiMessagesOptions, b0 as TranscriptEntry, b1 as TranscriptRole, b2 as TranscriptsApi, b3 as TranscriptsConfig, b4 as UserInfo, b5 as WebhookOptions, p as deriveChannelId, v as isPostableObject, t as toAiMessages } from './chat-D9UYaaNO.js';
1
+ import { ay as PostableObject, b as Adapter, az as PostableObjectContext, aN as StreamChunk, aU as ThreadHistoryCache, aV as ThreadHistoryConfig, aO as StreamEvent, L as EmojiFormats, M as EmojiMapConfig, N as EmojiValue, b4 as WellKnownEmoji, G as CustomEmojiMap, c as AdapterPostableMessage } from './chat-BjhJs_sP.js';
2
+ export { A as ActionEvent, a as ActionHandler, d as AiAssistantMessage, e as AiFilePart, f as AiImagePart, g as AiMessage, h as AiMessagePart, i as AiTextPart, j as AiUserMessage, k as AppHomeOpenedEvent, l as AppHomeOpenedHandler, m as AppendInput, n as AppendOptions, o as AssistantContextChangedEvent, p as AssistantContextChangedHandler, q as AssistantThreadStartedEvent, r as AssistantThreadStartedHandler, s as Attachment, t as Author, C as Channel, u as ChannelImpl, v as ChannelInfo, w as ChannelVisibility, x as Chat, y as ChatConfig, z as ChatInstance, B as ConcurrencyConfig, D as ConcurrencyStrategy, E as ConsoleLogger, F as CountQuery, H as DeleteTarget, I as DirectMessageHandler, J as DurationString, K as Emoji, O as EphemeralMessage, P as FetchDirection, Q as FetchOptions, R as FetchResult, S as FileUpload, T as FormattedContent, U as IdentityContext, V as IdentityResolver, W as LinkPreview, X as ListQuery, Y as ListThreadsOptions, Z as ListThreadsResult, _ as Lock, $ as LockScope, a0 as LockScopeContext, a1 as LogLevel, a2 as Logger, a3 as MarkdownTextChunk, a4 as MemberJoinedChannelEvent, a5 as MemberJoinedChannelHandler, a6 as MentionHandler, a7 as Message, a8 as MessageContext, a9 as MessageData, aa as MessageHandler, ab as MessageMetadata, ac as MessageSubject, ad as ModalClearResponse, ae as ModalCloseEvent, af as ModalCloseHandler, ag as ModalCloseResponse, ah as ModalErrorsResponse, ai as ModalPushResponse, aj as ModalResponse, ak as ModalSubmitEvent, al as ModalSubmitHandler, am as ModalUpdateResponse, an as OptionsLoadEvent, ao as OptionsLoadGroup, ap as OptionsLoadHandler, aq as OptionsLoadResult, ar as PlanUpdateChunk, as as PostEphemeralOptions, at as Postable, au as PostableAst, av as PostableCard, aw as PostableMarkdown, ax as PostableMessage, aA as PostableRaw, aB as QueueEntry, aC as RawMessage, aD as ReactionEvent, aE as ReactionHandler, aF as ScheduledMessage, aG as SentMessage, aH as SerializedChannel, aI as SerializedMessage, aJ as SerializedThread, aK as SlashCommandEvent, aL as SlashCommandHandler, aM as StateAdapter, aP as StreamOptions, aQ as SubscribedMessageHandler, aR as THREAD_STATE_TTL_MS, aS as TaskUpdateChunk, aT as Thread, aW as ThreadImpl, aX as ThreadInfo, aY as ThreadSummary, aZ as ToAiMessagesOptions, a_ as TranscriptEntry, a$ as TranscriptRole, b0 as TranscriptsApi, b1 as TranscriptsConfig, b2 as UserInfo, b3 as WebhookOptions, b5 as deriveChannelId, b6 as isPostableObject, b7 as toAiMessages } from './chat-BjhJs_sP.js';
3
3
  import { Root, List, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, Paragraph, Strong, TableCell, Table as Table$1, TableRow, Text } from 'mdast';
4
4
  export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Table as MdastTable, Nodes, Paragraph, Root, Strong, TableCell, TableRow, Text } from 'mdast';
5
- import { C as CardElement, a as CardChild, A as ActionsComponent, B as ButtonComponent, b as CardComponent, c as cardChildToFallbackText$1, d as CardLinkComponent, T as TextComponent, D as DividerComponent, F as FieldComponent, e as FieldsComponent, f as fromReactElement$1, I as ImageComponent, i as isCardElement$1, g as isJSX$1, L as LinkButtonComponent, S as SectionComponent, h as Table$2, t as toCardElement$1, j as toModalElement$1, k as fromReactModalElement$1, l as isModalElement$1, E as ExternalSelectComponent, M as ModalComponent, R as RadioSelectComponent, m as SelectComponent, n as SelectOptionComponent, o as TextInputComponent } from './jsx-runtime-CFq1K_Ve.js';
6
- export { p as ActionsElement, q as ButtonElement, r as ButtonOptions, U as ButtonProps, s as ButtonStyle, V as CardJSXElement, W as CardJSXProps, X as CardLinkProps, u as CardOptions, Y as CardProps, Z as ChatElement, _ as ContainerProps, v as DividerElement, $ as DividerProps, a9 as ExternalSelectElement, aa as ExternalSelectOptions, a0 as ExternalSelectProps, w as FieldElement, a1 as FieldProps, x as FieldsElement, y as ImageElement, a2 as ImageProps, z as LinkButtonElement, G as LinkButtonOptions, a3 as LinkButtonProps, H as LinkElement, ab as ModalChild, ac as ModalElement, ad as ModalOptions, a4 as ModalProps, ae as RadioSelectElement, af as RadioSelectOptions, J as SectionElement, ag as SelectElement, ah as SelectOptionElement, a5 as SelectOptionProps, ai as SelectOptions, a6 as SelectProps, K as TableAlignment, N as TableElement, O as TableOptions, P as TextElement, aj as TextInputElement, ak as TextInputOptions, a7 as TextInputProps, a8 as TextProps, Q as TextStyle } from './jsx-runtime-CFq1K_Ve.js';
5
+ import { g as CardElement, C as CardChild, A as ActionsComponent, B as ButtonComponent, f as CardComponent, j as CardLinkComponent, a9 as TextComponent, D as DividerComponent, E as ExternalSelectComponent, F as FieldComponent, w as FieldsComponent, I as ImageComponent, L as LinkButtonComponent, P as ModalComponent, T as RadioSelectComponent, W as SectionComponent, Y as SelectComponent, _ as SelectOptionComponent, a3 as Table$2, ab as TextInputComponent, ah as cardChildToFallbackText$1, ai as fromReactElement$1, aj as fromReactModalElement$1, ak as isCardElement$1, am as isJSX$1, an as isModalElement$1, ar as toCardElement$1, as as toModalElement$1 } from './jsx-runtime-CzthIo1o.js';
6
+ export { a as ActionsElement, b as ButtonElement, c as ButtonOptions, d as ButtonProps, e as ButtonStyle, h as CardJSXElement, i as CardJSXProps, k as CardLinkProps, l as CardOptions, m as CardProps, n as ChatElement, o as ContainerProps, p as DividerElement, q as DividerProps, r as ExternalSelectElement, s as ExternalSelectOptions, t as ExternalSelectProps, u as FieldElement, v as FieldProps, x as FieldsElement, z as ImageElement, G as ImageProps, H as LinkButtonElement, K as LinkButtonOptions, M as LinkButtonProps, N as LinkElement, O as ModalChild, Q as ModalElement, R as ModalOptions, S as ModalProps, U as RadioSelectElement, V as RadioSelectOptions, X as SectionElement, Z as SelectElement, $ as SelectOptionElement, a0 as SelectOptionProps, a1 as SelectOptions, a2 as SelectProps, a4 as TableAlignment, a6 as TableElement, a7 as TableOptions, aa as TextElement, ac as TextInputElement, ad as TextInputOptions, ae as TextInputProps, af as TextProps, ag as TextStyle } from './jsx-runtime-CzthIo1o.js';
7
7
  import '@workflow/serde';
8
8
 
9
9
  /**
package/dist/index.js CHANGED
@@ -60,7 +60,7 @@ import {
60
60
  toModalElement,
61
61
  toPlainText,
62
62
  walkAst
63
- } from "./chunk-V25FKIIL.js";
63
+ } from "./chunk-LNXHNIFE.js";
64
64
  import {
65
65
  toAiMessages
66
66
  } from "./chunk-HD375J7S.js";
@@ -1504,7 +1504,10 @@ var ThreadImpl = class _ThreadImpl {
1504
1504
  */
1505
1505
  async handleStream(rawStream, callerOptions) {
1506
1506
  const textStream = fromFullStream(rawStream);
1507
- const options = { ...callerOptions };
1507
+ const options = {
1508
+ updateIntervalMs: this._streamingUpdateIntervalMs,
1509
+ ...callerOptions
1510
+ };
1508
1511
  if (this._currentMessage) {
1509
1512
  options.recipientUserId = this._currentMessage.author.userId;
1510
1513
  options.recipientTeamId = this.extractSlackRecipientTeamId(
@@ -1533,15 +1536,17 @@ var ThreadImpl = class _ThreadImpl {
1533
1536
  }
1534
1537
  };
1535
1538
  const raw = await this.adapter.stream(this.id, wrappedStream, options);
1536
- const sent = this.createSentMessage(
1537
- raw.id,
1538
- { markdown: accumulated },
1539
- raw.threadId
1540
- );
1541
- if (this._threadHistory) {
1542
- await this._threadHistory.append(this.id, new Message(sent));
1539
+ if (raw) {
1540
+ const sent = this.createSentMessage(
1541
+ raw.id,
1542
+ { markdown: accumulated },
1543
+ raw.threadId
1544
+ );
1545
+ if (this._threadHistory) {
1546
+ await this._threadHistory.append(this.id, new Message(sent));
1547
+ }
1548
+ return sent;
1543
1549
  }
1544
- return sent;
1545
1550
  }
1546
1551
  const textOnlyStream = {
1547
1552
  [Symbol.asyncIterator]: () => {
@@ -68,6 +68,8 @@ interface ButtonElement {
68
68
  }
69
69
  /** Link button element that opens a URL */
70
70
  interface LinkButtonElement {
71
+ /** Optional action identifier emitted by platforms that report link clicks */
72
+ id?: string;
71
73
  /** Button label text */
72
74
  label: string;
73
75
  /** Visual style */
@@ -268,6 +270,8 @@ interface ButtonOptions {
268
270
  declare function Button(options: ButtonOptions): ButtonElement;
269
271
  /** Options for LinkButton */
270
272
  interface LinkButtonOptions {
273
+ /** Optional action identifier emitted by platforms that report link clicks */
274
+ id?: string;
271
275
  /** Button label text */
272
276
  label: string;
273
277
  /** Visual style */
@@ -546,6 +550,7 @@ interface ButtonProps {
546
550
  /** Props for LinkButton component in JSX */
547
551
  interface LinkButtonProps {
548
552
  children?: string | number | (string | number | undefined)[];
553
+ id?: string;
549
554
  label?: string;
550
555
  style?: ButtonStyle;
551
556
  url: string;
@@ -779,4 +784,4 @@ declare namespace JSX {
779
784
  }
780
785
  }
781
786
 
782
- export { type DividerProps as $, type ActionsComponent as A, type ButtonComponent as B, type CardElement as C, type DividerComponent as D, type ExternalSelectComponent as E, type FieldComponent as F, type LinkButtonOptions as G, type LinkElement as H, type ImageComponent as I, type SectionElement as J, type TableAlignment as K, type LinkButtonComponent as L, type ModalComponent as M, type TableElement as N, type TableOptions as O, type TextElement as P, type TextStyle as Q, type RadioSelectComponent as R, type SectionComponent as S, type TextComponent as T, type ButtonProps as U, type CardJSXElement as V, type CardJSXProps as W, type CardLinkProps as X, type CardProps as Y, type ChatElement as Z, type ContainerProps as _, type CardChild as a, type ExternalSelectProps as a0, type FieldProps as a1, type ImageProps as a2, type LinkButtonProps as a3, type ModalProps as a4, type SelectOptionProps as a5, type SelectProps as a6, type TextInputProps as a7, type TextProps as a8, type ExternalSelectElement as a9, type ExternalSelectOptions as aa, type ModalChild as ab, type ModalElement as ac, type ModalOptions as ad, type RadioSelectElement as ae, type RadioSelectOptions as af, type SelectElement as ag, type SelectOptionElement as ah, type SelectOptions as ai, type TextInputElement as aj, type TextInputOptions as ak, type TableProps as al, type TableComponent as am, isCardLinkProps as an, jsx as ao, jsxs as ap, jsxDEV as aq, Fragment as ar, JSX as as, type CardComponent as b, cardChildToFallbackText as c, type CardLinkComponent as d, type FieldsComponent as e, fromReactElement as f, isJSX as g, Table as h, isCardElement as i, toModalElement as j, fromReactModalElement as k, isModalElement as l, type SelectComponent as m, type SelectOptionComponent as n, type TextInputComponent as o, type ActionsElement as p, type ButtonElement as q, type ButtonOptions as r, type ButtonStyle as s, toCardElement as t, type CardOptions as u, type DividerElement as v, type FieldElement as w, type FieldsElement as x, type ImageElement as y, type LinkButtonElement as z };
787
+ export { type SelectOptionElement as $, type ActionsComponent as A, type ButtonComponent as B, type CardChild as C, type DividerComponent as D, type ExternalSelectComponent as E, type FieldComponent as F, type ImageProps as G, type LinkButtonElement as H, type ImageComponent as I, JSX as J, type LinkButtonOptions as K, type LinkButtonComponent as L, type LinkButtonProps as M, type LinkElement as N, type ModalChild as O, type ModalComponent as P, type ModalElement as Q, type ModalOptions as R, type ModalProps as S, type RadioSelectComponent as T, type RadioSelectElement as U, type RadioSelectOptions as V, type SectionComponent as W, type SectionElement as X, type SelectComponent as Y, type SelectElement as Z, type SelectOptionComponent as _, type ActionsElement as a, type SelectOptionProps as a0, type SelectOptions as a1, type SelectProps as a2, Table as a3, type TableAlignment as a4, type TableComponent as a5, type TableElement as a6, type TableOptions as a7, type TableProps as a8, type TextComponent as a9, type TextElement as aa, type TextInputComponent as ab, type TextInputElement as ac, type TextInputOptions as ad, type TextInputProps as ae, type TextProps as af, type TextStyle as ag, cardChildToFallbackText as ah, fromReactElement as ai, fromReactModalElement as aj, isCardElement as ak, isCardLinkProps as al, isJSX as am, isModalElement as an, jsx as ao, jsxDEV as ap, jsxs as aq, toCardElement as ar, toModalElement as as, type ButtonElement as b, type ButtonOptions as c, type ButtonProps as d, type ButtonStyle as e, type CardComponent as f, type CardElement as g, type CardJSXElement as h, type CardJSXProps as i, type CardLinkComponent as j, type CardLinkProps as k, type CardOptions as l, type CardProps as m, type ChatElement as n, type ContainerProps as o, type DividerElement as p, type DividerProps as q, type ExternalSelectElement as r, type ExternalSelectOptions as s, type ExternalSelectProps as t, type FieldElement as u, type FieldProps as v, type FieldsComponent as w, type FieldsElement as x, Fragment as y, type ImageElement as z };
@@ -1 +1 @@
1
- export { A as ActionsComponent, B as ButtonComponent, U as ButtonProps, b as CardComponent, V as CardJSXElement, W as CardJSXProps, d as CardLinkComponent, X as CardLinkProps, Y as CardProps, Z as ChatElement, _ as ContainerProps, D as DividerComponent, $ as DividerProps, E as ExternalSelectComponent, a0 as ExternalSelectProps, F as FieldComponent, a1 as FieldProps, e as FieldsComponent, ar as Fragment, I as ImageComponent, a2 as ImageProps, as as JSX, L as LinkButtonComponent, a3 as LinkButtonProps, M as ModalComponent, a4 as ModalProps, R as RadioSelectComponent, S as SectionComponent, m as SelectComponent, n as SelectOptionComponent, a5 as SelectOptionProps, a6 as SelectProps, am as TableComponent, al as TableProps, T as TextComponent, o as TextInputComponent, a7 as TextInputProps, a8 as TextProps, an as isCardLinkProps, g as isJSX, ao as jsx, aq as jsxDEV, ap as jsxs, t as toCardElement, j as toModalElement } from './jsx-runtime-CFq1K_Ve.js';
1
+ export { A as ActionsComponent, B as ButtonComponent, d as ButtonProps, f as CardComponent, h as CardJSXElement, i as CardJSXProps, j as CardLinkComponent, k as CardLinkProps, m as CardProps, n as ChatElement, o as ContainerProps, D as DividerComponent, q as DividerProps, E as ExternalSelectComponent, t as ExternalSelectProps, F as FieldComponent, v as FieldProps, w as FieldsComponent, y as Fragment, I as ImageComponent, G as ImageProps, J as JSX, L as LinkButtonComponent, M as LinkButtonProps, P as ModalComponent, S as ModalProps, T as RadioSelectComponent, W as SectionComponent, Y as SelectComponent, _ as SelectOptionComponent, a0 as SelectOptionProps, a2 as SelectProps, a5 as TableComponent, a8 as TableProps, a9 as TextComponent, ab as TextInputComponent, ae as TextInputProps, af as TextProps, al as isCardLinkProps, am as isJSX, ao as jsx, ap as jsxDEV, aq as jsxs, ar as toCardElement, as as toModalElement } from './jsx-runtime-CzthIo1o.js';
@@ -7,7 +7,7 @@ import {
7
7
  jsxs,
8
8
  toCardElement,
9
9
  toModalElement
10
- } from "./chunk-V25FKIIL.js";
10
+ } from "./chunk-LNXHNIFE.js";
11
11
  export {
12
12
  Fragment,
13
13
  isCardLinkProps,
package/docs/adapters.mdx CHANGED
@@ -1,146 +1,159 @@
1
1
  ---
2
- title: Platform Adapters
3
- description: Platform-specific adapters that connect your bot to any messaging platform.
2
+ title: Overview
3
+ description: Overview of Chat SDK adapters and the static adapter catalog.
4
4
  type: overview
5
5
  prerequisites:
6
6
  - /docs/getting-started
7
7
  ---
8
8
 
9
- Adapters handle webhook verification, message parsing, and API calls for each platform. Install only the adapters you need. Browse all available adapters — including community-built ones — on the [Adapters](/adapters) page.
9
+ Adapters connect Chat SDK to messaging platforms and state backends. Install only the adapters you need, then register them on your `Chat` instance.
10
10
 
11
- Need a browser chat UI? See the [Web adapter](/adapters/official/web) — it speaks the AI SDK UI stream protocol and works with React (`@ai-sdk/react`), Vue (`@ai-sdk/vue`), and Svelte (`@ai-sdk/svelte`), so the same bot serves Slack, Teams, **and** any browser framework out of the box.
11
+ Use the dedicated guides for adapter-specific concepts:
12
+
13
+ - [Platform Adapters](/docs/platform-adapters) cover webhook verification, message parsing, API calls, feature support, and multi-platform bots.
14
+ - [State Adapters](/docs/state-adapters) cover subscriptions, distributed locking, and caching.
15
+ - Browse all official, vendor-official, and community adapters on the [Adapters](/adapters) listing page.
12
16
 
13
17
  Ready to build your own? Follow the [building](/docs/contributing/building) guide.
14
18
 
15
- ## Feature matrix
16
-
17
- <GlobalFeatureMatrix type="platform" />
18
- ### Messaging
19
-
20
- | Feature | [Slack](/adapters/slack) | [Teams](/adapters/teams) | [Google Chat](/adapters/google-chat) | [Discord](/adapters/discord) | [Telegram](/adapters/telegram) | [GitHub](/adapters/github) | [Linear](/adapters/linear) | [WhatsApp](/adapters/whatsapp) | [Messenger](/adapters/messenger) |
21
- |---------|-------|-------|-------------|---------|---------|--------|--------|-----------|-----------|
22
- | Post message | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
23
- | Edit message | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Partial | <Cross /> | <Cross /> |
24
- | Delete message | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Partial | <Cross /> | <Cross /> |
25
- | File uploads | <Check /> | <Check /> | <Cross /> | <Check /> | <Warn /> Single file/media | <Cross /> | <Cross /> | <Check /> Images, audio, docs | <Cross /> |
26
- | Streaming | <Check /> Native | <Warn /> Native (DMs) / Buffered | <Warn /> Post+Edit | <Warn /> Post+Edit | <Warn /> Post+Edit | <Warn /> Buffered | <Warn /> Agent sessions / Post+Edit | <Warn /> Buffered | <Warn /> Buffered |
27
- | Scheduled messages | <Check /> Native | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
28
-
29
- ### Rich content
30
-
31
- | Feature | Slack | Teams | Google Chat | Discord | Telegram | GitHub | Linear | WhatsApp | Messenger |
32
- |---------|-------|-------|-------------|---------|----------|--------|--------|-----------|-----------|
33
- | Card format | Block Kit | Adaptive Cards | Google Chat Cards | Embeds | Markdown + inline keyboard buttons | GFM Markdown | Markdown | WhatsApp templates | Generic/Button Templates |
34
- | Buttons | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Inline keyboard callbacks | <Cross /> | <Cross /> | <Check /> Interactive replies | <Warn /> Max 3, postback |
35
- | Link buttons | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Inline keyboard URLs | <Cross /> | <Cross /> | <Cross /> | <Check /> |
36
- | Select menus | <Check /> | <Cross /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
37
- | Tables | <Check /> Block Kit | <Check /> GFM | <Warn /> ASCII | <Check /> GFM | <Warn /> ASCII | <Check /> GFM | <Check /> GFM | <Cross /> | <Warn /> ASCII |
38
- | Fields | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Template variables | <Warn /> ASCII |
39
- | Images in cards | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Check /> | <Cross /> | <Check /> | <Check /> |
40
- | Modals | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
41
-
42
- ### Conversations
43
-
44
- | Feature | Slack | Teams | Google Chat | Discord | Telegram | GitHub | Linear | WhatsApp | Messenger |
45
- |---------|-------|-------|-------------|---------|----------|--------|--------|-----------|-----------|
46
- | Slash commands | <Check /> | <Cross /> | <Cross /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
47
- | Mentions | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Check /> |
48
- | Add reactions | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
49
- | Remove reactions | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> | <Warn /> | <Warn /> | <Check /> | <Cross /> |
50
- | Typing indicator | <Check /> | <Check /> | <Cross /> | <Check /> | <Check /> | <Cross /> | <Warn /> Agent sessions | <Cross /> | <Check /> |
51
- | DMs | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Check /> | <Check /> |
52
- | Ephemeral messages | <Check /> Native | <Cross /> | <Check /> Native | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
53
- | User lookup ([`getUser`](/docs/api/chat#getuser)) | <Check /> | <Warn /> Cached | <Warn /> Cached | <Check /> | <Warn /> Seen users | <Check /> | <Check /> | <Cross /> | <Cross /> |
54
- | Parent subject ([`message.subject`](/docs/subject)) | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
55
- | Native client ([`.webClient` / `.octokit` / `.linearClient`](/docs/api/chat#getadapter)) | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
56
- | Custom API endpoint (`apiUrl`) | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
57
-
58
- ### Message history
59
-
60
- | Feature | Slack | Teams | Google Chat | Discord | Telegram | GitHub | Linear | WhatsApp | Messenger |
61
- |---------|-------|-------|-------------|---------|----------|--------|--------|-----------|-----------|
62
- | Fetch messages | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Cached | <Check /> | <Check /> | <Warn /> Cached sent messages only | <Warn /> Cached sent messages only |
63
- | Fetch single message | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Warn /> Cached | <Cross /> | <Cross /> | <Cross /> | <Warn /> Cached |
64
- | Fetch thread info | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
65
- | Fetch channel messages | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Cached | <Check /> | <Cross /> | <Cross /> | <Warn /> Cached |
66
- | List threads | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Check /> | <Cross /> | <Cross /> | <Cross /> |
67
- | Fetch channel info | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Check /> |
68
- | Post channel message | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Check /> | <Check /> |
69
-
70
- <Callout type="info">
71
- <Warn /> indicates partial support — the feature works with limitations. See individual adapter pages for details.
72
- </Callout>
73
-
74
- ## How adapters work
75
-
76
- Each adapter implements a standard interface that the `Chat` class uses to route events and send messages. When a webhook arrives:
77
-
78
- 1. The adapter verifies the request signature
79
- 2. Parses the platform-specific payload into a normalized `Message`
80
- 3. Routes to your handlers via the `Chat` class
81
- 4. Converts outgoing messages from markdown/AST/cards to the platform's native format
82
-
83
- ## Using multiple adapters
84
-
85
- Register multiple [adapters](/adapters) and your event handlers work across all of them:
86
-
87
- ```typescript title="lib/bot.ts" lineNumbers
88
- import { Chat } from "chat";
89
- import { createSlackAdapter } from "@chat-adapter/slack";
90
- import { createTeamsAdapter } from "@chat-adapter/teams";
91
- import { createGoogleChatAdapter } from "@chat-adapter/gchat";
92
- import { createRedisState } from "@chat-adapter/state-redis";
93
-
94
- const bot = new Chat({
95
- userName: "mybot",
96
- adapters: {
97
- slack: createSlackAdapter(),
98
- teams: createTeamsAdapter(),
99
- gchat: createGoogleChatAdapter(),
100
- },
101
- state: createRedisState(),
102
- });
103
-
104
- // This handler fires for mentions on any platform
105
- bot.onNewMention(async (thread) => {
106
- await thread.subscribe();
107
- await thread.post("Hello!");
108
- });
109
- ```
19
+ ## Adapter catalog (`chat/adapters`)
110
20
 
111
- Each adapter auto-detects credentials from environment variables, so you only need to pass config when overriding defaults.
21
+ The `chat/adapters` subpath is a static catalog of official and vendor-official adapters. It imports no adapter packages, so you can use it from setup screens, build scripts, or onboarding flows without pulling in Slack, Teams, Redis, or other platform SDKs.
112
22
 
113
- <Callout type="info">
114
- The examples above use Redis for state. See [State Adapters](/docs/state) for all available options.
115
- </Callout>
23
+ ```typescript title="scripts/list-adapters.ts" lineNumbers
24
+ import { ADAPTER_NAMES, getAdapter } from "chat/adapters";
116
25
 
117
- Each adapter creates a webhook handler accessible via `bot.webhooks.<name>`.
26
+ for (const slug of ADAPTER_NAMES) {
27
+ const adapter = getAdapter(slug);
28
+ console.log(adapter.name, adapter.packageName, adapter.peerDeps);
29
+ }
30
+ ```
118
31
 
119
- ## Customizing an adapter via subclassing
32
+ Use the env helpers when you need to show setup instructions or inject secrets for one adapter:
120
33
 
121
- Each official adapter exposes its extension surface as `protected` members so you can subclass it to override or extend platform-specific behavior without forking the package. Use this when you need to handle a payload type the built-in adapter doesn't cover, intercept verification, or wrap an existing handler.
34
+ ```typescript lineNumbers
35
+ import { getAdapter, getSecretEnvVars } from "chat/adapters";
122
36
 
123
- ```typescript title="lib/custom-telegram.ts" lineNumbers
124
- import { TelegramAdapter, type TelegramUpdate } from "@chat-adapter/telegram";
125
- import type { WebhookOptions } from "chat";
37
+ const slack = getAdapter("slack");
38
+ const secrets = getSecretEnvVars("slack").map((envVar) => envVar.key);
126
39
 
127
- export class CustomTelegramAdapter extends TelegramAdapter {
128
- protected override processUpdate(
129
- update: TelegramUpdate,
130
- options?: WebhookOptions
131
- ): void {
132
- // Handle a payload type the base adapter doesn't, e.g. chat_join_request.
133
- if ("chat_join_request" in update) {
134
- this.logger.info("Received chat_join_request", { update });
135
- return;
136
- }
137
- super.processUpdate(update, options);
138
- }
139
- }
40
+ console.log(slack.name, secrets);
140
41
  ```
141
42
 
142
- Construct your subclass anywhere you'd construct the base adapter — for example, `adapters: { telegram: new CustomTelegramAdapter({ ... }) }`. Members marked `private` (internal caches, in-flight runtime state, one-shot warning flags) intentionally remain inaccessible; if you find a hook you need that isn't `protected`, please open an issue.
143
-
144
- <Callout type="warn">
145
- The `protected` extension surface is intentionally broader than the public API but is not yet considered fully stable. Method signatures may evolve (renames, parameter changes, new hook splits) in minor releases as we learn from real-world subclasses. Pin the adapter version you build against, watch the changelog for the affected adapter, and prefer overriding the smallest hook that solves your problem so upgrades stay easy. If you rely on a particular hook, please open an issue so we can promote it to a stable, documented extension point.
146
- </Callout>
43
+ The catalog intentionally covers official and vendor-official adapters. Community adapters live on the [Adapters](/adapters) listing page.
44
+
45
+ ### Environment specs
46
+
47
+ Each adapter entry includes an `env` spec:
48
+
49
+ - `required` lists variables needed regardless of auth mode.
50
+ - `credentialModes` groups mutually exclusive ways to authenticate, such as a bot token vs OAuth client credentials.
51
+ - `optional` lists tuning variables that are safe to omit.
52
+ - `config` lists constructor options that do not have an environment-variable equivalent.
53
+
54
+ ### Types
55
+
56
+ The main `CatalogAdapter` metadata shape is:
57
+
58
+ <TypeTable
59
+ type={{
60
+ slug: {
61
+ type: "string",
62
+ description: "Stable catalog slug. Matches the key in `ADAPTERS`.",
63
+ },
64
+ name: {
65
+ type: "string",
66
+ description: "Display name.",
67
+ },
68
+ description: {
69
+ type: "string",
70
+ description: "One-line summary of what the adapter connects to.",
71
+ },
72
+ packageName: {
73
+ type: "string",
74
+ description: "NPM package that provides the adapter implementation.",
75
+ },
76
+ type: {
77
+ type: '"platform" | "state"',
78
+ description: "Whether the adapter connects to a platform or stores Chat SDK state.",
79
+ },
80
+ group: {
81
+ type: '"official" | "vendor-official"',
82
+ description: "Catalog group used by the docs adapter listing.",
83
+ },
84
+ peerDeps: {
85
+ type: "readonly string[]",
86
+ description: "Runtime packages the adapter expects the consuming app to provide or install alongside it.",
87
+ },
88
+ env: {
89
+ type: "AdapterEnvSpec",
90
+ description: "Environment variables and constructor-only configuration.",
91
+ },
92
+ }}
93
+ />
94
+
95
+ <TypeTable
96
+ type={{
97
+ required: {
98
+ type: "readonly EnvVar[]",
99
+ description: "Variables needed regardless of credential mode.",
100
+ },
101
+ credentialModes: {
102
+ type: "readonly EnvGroup[]",
103
+ description: "Mutually exclusive credential groups. A caller usually satisfies exactly one group.",
104
+ },
105
+ optional: {
106
+ type: "readonly EnvVar[]",
107
+ description: "Optional environment variables that tune behavior.",
108
+ },
109
+ config: {
110
+ type: "readonly string[]",
111
+ description: "Constructor options that have no environment-variable equivalent.",
112
+ },
113
+ notes: {
114
+ type: "string",
115
+ description: "Additional caveats that do not fit the structured fields.",
116
+ },
117
+ }}
118
+ />
119
+
120
+ <TypeTable
121
+ type={{
122
+ label: {
123
+ type: "string",
124
+ description: "Human-readable name for this credential mode.",
125
+ },
126
+ vars: {
127
+ type: "readonly EnvVar[]",
128
+ description: "Variables that together satisfy this mode.",
129
+ },
130
+ }}
131
+ />
132
+
133
+ <TypeTable
134
+ type={{
135
+ key: {
136
+ type: "string",
137
+ description: "Canonical environment variable name.",
138
+ },
139
+ description: {
140
+ type: "string",
141
+ description: "Short description of what the value configures.",
142
+ },
143
+ secret: {
144
+ type: "boolean",
145
+ description: "Whether the value should be masked in logs and setup UIs.",
146
+ },
147
+ aliases: {
148
+ type: "readonly string[]",
149
+ description: "Alternative variable names accepted for the same value.",
150
+ },
151
+ }}
152
+ />
153
+
154
+ ### Helpers
155
+
156
+ - `getAdapter(slug)` returns one catalog entry, or `undefined` for unknown slugs.
157
+ - `isAdapterSlug(slug)` narrows a string to `AdapterSlug`.
158
+ - `listEnvVars(slug)` flattens required, credential-mode, and optional env vars, de-duplicated by key.
159
+ - `getSecretEnvVars(slug)` returns the subset of `listEnvVars(slug)` marked as secrets.
package/docs/ai/index.mdx CHANGED
@@ -61,3 +61,9 @@ bot.onSubscribedMessage(async (thread) => {
61
61
  - import { toAiMessages } from "chat";
62
62
  + import { toAiMessages } from "chat/ai";
63
63
  ```
64
+
65
+ ## Resources
66
+
67
+ - [Human-in-the-Loop with Chat SDK and Workflow SDK](https://vercel.com/kb/guide/human-in-the-loop-with-chat-sdk-and-workflow-sdk?utm_source=chat-sdk_site&utm_medium=docs&utm_campaign=ai&utm_content=human-in-the-loop-with-chat-sdk-and-workflow-sdk) — Pause durable workflows on Slack approval cards using Chat SDK and Workflow SDK. Uses `createWebhook` to suspend workflows until a button click, with patterns for multi-stage approvals, timeouts via durable sleep, and approver validation.
68
+
69
+ See all guides and templates on the [resources](/resources?utm_source=chat-sdk_site&utm_medium=docs&utm_campaign=ai&utm_content=resources) page.
@@ -130,14 +130,21 @@ CardLink({ url: "https://example.com", label: "Visit Site" })
130
130
 
131
131
  ## LinkButton
132
132
 
133
- Button that opens a URL. No `onAction` handler needed.
133
+ Button that opens a URL. No `onAction` handler needed for navigation. On
134
+ platforms that emit link-button click events, such as Slack, pass `id` when you
135
+ need a stable action identifier for routing or analytics.
134
136
 
135
137
  ```typescript
136
138
  LinkButton({ url: "https://example.com", label: "View Docs" })
139
+ LinkButton({ id: "view_docs", url: "https://example.com", label: "View Docs" })
137
140
  ```
138
141
 
139
142
  <TypeTable
140
143
  type={{
144
+ id: {
145
+ description: 'Optional action identifier emitted by platforms that report link clicks.',
146
+ type: 'string',
147
+ },
141
148
  url: {
142
149
  description: 'URL to open when clicked.',
143
150
  type: 'string',
@@ -90,7 +90,11 @@ import { Message } from "chat";
90
90
 
91
91
  ### How `isMe` works
92
92
 
93
- Each adapter detects whether a message came from the bot itself. The detection logic varies by platform:
93
+ Each adapter detects whether a message came from the bot itself. Chat SDK filters `isMe: true` messages before handlers run so bot replies do not loop back into `onNewMessage`, `onNewMention`, or subscribed-thread handlers.
94
+
95
+ `isMe` means "sent by this bot/runtime", not "sent by the authenticated user or account". For adapters backed by a user-owned account, do not blindly map platform fields like `fromMe` to `isMe`. Only set `isMe: true` for messages the adapter sent itself. If the platform echoes sent messages back through the webhook, track sent message IDs and mark only those echoes as `isMe: true`.
96
+
97
+ The detection logic varies by platform:
94
98
 
95
99
  | Platform | Detection method |
96
100
  |----------|-----------------|
package/docs/cards.mdx CHANGED
@@ -141,12 +141,20 @@ Or with children as the label:
141
141
 
142
142
  ### LinkButton
143
143
 
144
- Opens an external URL. No `onAction` handler needed.
144
+ Opens an external URL. No `onAction` handler needed for navigation. On platforms
145
+ that emit link-button click events, such as Slack, pass `id` when you need a
146
+ stable action identifier for routing or analytics.
145
147
 
146
148
  ```tsx title="lib/bot.tsx"
147
149
  <LinkButton url="https://example.com/order/1234">View Order</LinkButton>
148
150
  ```
149
151
 
152
+ ```tsx title="lib/bot.tsx"
153
+ <LinkButton id="view_order" url="https://example.com/order/1234">
154
+ View Order
155
+ </LinkButton>
156
+ ```
157
+
150
158
  ### Actions
151
159
 
152
160
  Container for buttons and interactive elements.