chat 4.30.0 → 4.32.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.
- package/README.md +33 -7
- package/dist/adapters/index.d.ts +622 -0
- package/dist/adapters/index.js +799 -0
- package/dist/ai/index.d.ts +3 -3
- package/dist/{chat-BPjXsoIl.d.ts → chat-Dm1vQU3i.d.ts} +3 -2
- package/dist/{chunk-V25FKIIL.js → chunk-LNXHNIFE.js} +2 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.js +22 -10
- package/dist/{jsx-runtime-CnDs8rPr.d.ts → jsx-runtime-CzthIo1o.d.ts} +5 -0
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +1 -1
- package/docs/adapters.mdx +140 -127
- package/docs/ai/index.mdx +2 -2
- package/docs/api/cards.mdx +8 -1
- package/docs/api/message.mdx +5 -1
- package/docs/cards.mdx +9 -1
- package/docs/concurrency.mdx +1 -1
- package/docs/contributing/building.mdx +6 -0
- package/docs/conversation-history.mdx +1 -1
- package/docs/create-chat-sdk.mdx +143 -0
- package/docs/ephemeral-messages.mdx +2 -0
- package/docs/error-handling.mdx +1 -1
- package/docs/getting-started.mdx +4 -4
- package/docs/index.mdx +1 -1
- package/docs/meta.json +4 -1
- package/docs/platform-adapters.mdx +148 -0
- package/docs/slash-commands.mdx +8 -1
- package/docs/streaming.mdx +7 -4
- package/docs/teams-primitives.mdx +255 -0
- package/docs/testing.mdx +1 -1
- package/docs/threads-messages-channels.mdx +2 -2
- package/docs/usage.mdx +3 -3
- package/package.json +24 -5
- package/resources/guides/ai-gateway-and-ai-sdk.md +224 -0
- package/resources/guides/build-a-slack-bot-with-vercel-connect.md +239 -0
- package/resources/guides/create-a-discord-support-bot-with-nuxt-and-redis.md +2 -2
- package/resources/guides/daily-digest-bot-with-chat-sdk-and-workflow-sdk.md +306 -0
- package/resources/guides/how-to-build-a-slack-bot-with-next-js-and-redis.md +1 -1
- package/resources/guides/liveblocks-chat-sdk-ai-sdk.md +0 -2
- package/resources/guides/ship-a-github-code-review-bot-with-hono-and-redis.md +1 -1
- package/resources/guides/slack-bot-vercel-blob.md +13 -13
- package/resources/guides/vercel-connect.md +210 -0
- package/resources/templates.json +5 -0
- /package/docs/{state.mdx → state-adapters.mdx} +0 -0
package/dist/ai/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { x as Chat, w as ChannelVisibility } from '../chat-
|
|
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-
|
|
1
|
+
import { x as Chat, w as ChannelVisibility } from '../chat-Dm1vQU3i.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-Dm1vQU3i.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-
|
|
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 { n as ChatElement, g as CardElement, Q as ModalElement, $ as SelectOptionElement } from './jsx-runtime-
|
|
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) */
|
|
@@ -1458,7 +1458,7 @@ interface Author {
|
|
|
1458
1458
|
fullName: string;
|
|
1459
1459
|
/** Whether the author is a bot */
|
|
1460
1460
|
isBot: boolean | "unknown";
|
|
1461
|
-
/** Whether
|
|
1461
|
+
/** Whether this message was sent by this bot/runtime */
|
|
1462
1462
|
isMe: boolean;
|
|
1463
1463
|
/** Unique user ID */
|
|
1464
1464
|
userId: string;
|
|
@@ -3138,6 +3138,7 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
|
|
|
3138
3138
|
* subscription status, mention detection, and pattern matching.
|
|
3139
3139
|
*/
|
|
3140
3140
|
private dispatchToHandlers;
|
|
3141
|
+
private setMentionFlags;
|
|
3141
3142
|
private createThread;
|
|
3142
3143
|
/**
|
|
3143
3144
|
* Detect if the bot was mentioned in the message.
|
|
@@ -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 { 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-
|
|
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-
|
|
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-Dm1vQU3i.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-Dm1vQU3i.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 { 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-
|
|
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-
|
|
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
|
/**
|
|
@@ -53,6 +53,8 @@ interface StartPlanOptions {
|
|
|
53
53
|
initialMessage: PlanContent;
|
|
54
54
|
}
|
|
55
55
|
interface AddTaskOptions {
|
|
56
|
+
/** When true (default), mark existing in_progress tasks complete before adding. */
|
|
57
|
+
autoCompletePrevious?: boolean;
|
|
56
58
|
/** Task details/substeps. */
|
|
57
59
|
children?: PlanContent;
|
|
58
60
|
title: PlanContent;
|
|
@@ -74,6 +76,7 @@ interface CompletePlanOptions {
|
|
|
74
76
|
*
|
|
75
77
|
* Create a plan with `new Plan({ initialMessage: "..." })` and post it with `thread.post(plan)`.
|
|
76
78
|
* After posting, use methods like `addTask()`, `updateTask()`, and `complete()` to update it.
|
|
79
|
+
* For parallel steps, pass `autoCompletePrevious: false` to `addTask()` and use `updateTask({ id })` to update individual tasks.
|
|
77
80
|
*
|
|
78
81
|
* @example
|
|
79
82
|
* ```typescript
|
package/dist/index.js
CHANGED
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
toModalElement,
|
|
61
61
|
toPlainText,
|
|
62
62
|
walkAst
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-LNXHNIFE.js";
|
|
64
64
|
import {
|
|
65
65
|
toAiMessages
|
|
66
66
|
} from "./chunk-HD375J7S.js";
|
|
@@ -3020,7 +3020,7 @@ var Chat = class {
|
|
|
3020
3020
|
author: event.user,
|
|
3021
3021
|
metadata: { dateSent: /* @__PURE__ */ new Date(), edited: false },
|
|
3022
3022
|
attachments: []
|
|
3023
|
-
}) :
|
|
3023
|
+
}) : void 0;
|
|
3024
3024
|
const thread = event.threadId ? await this.createThread(
|
|
3025
3025
|
event.adapter,
|
|
3026
3026
|
event.threadId,
|
|
@@ -3140,7 +3140,7 @@ var Chat = class {
|
|
|
3140
3140
|
const thread = await this.createThread(
|
|
3141
3141
|
event.adapter,
|
|
3142
3142
|
event.threadId,
|
|
3143
|
-
event.message
|
|
3143
|
+
event.message,
|
|
3144
3144
|
isSubscribed
|
|
3145
3145
|
);
|
|
3146
3146
|
const fullEvent = {
|
|
@@ -3228,7 +3228,7 @@ var Chat = class {
|
|
|
3228
3228
|
);
|
|
3229
3229
|
}
|
|
3230
3230
|
const threadId = await adapter.openDM(userId);
|
|
3231
|
-
return this.createThread(adapter, threadId,
|
|
3231
|
+
return this.createThread(adapter, threadId, void 0, false);
|
|
3232
3232
|
}
|
|
3233
3233
|
/**
|
|
3234
3234
|
* Look up user information by user ID.
|
|
@@ -3333,7 +3333,7 @@ var Chat = class {
|
|
|
3333
3333
|
"ADAPTER_NOT_FOUND"
|
|
3334
3334
|
);
|
|
3335
3335
|
}
|
|
3336
|
-
return this.createThread(adapter, threadId,
|
|
3336
|
+
return this.createThread(adapter, threadId, void 0, false);
|
|
3337
3337
|
}
|
|
3338
3338
|
/**
|
|
3339
3339
|
* Infer which adapter to use based on the userId format.
|
|
@@ -3754,7 +3754,7 @@ var Chat = class {
|
|
|
3754
3754
|
* subscription status, mention detection, and pattern matching.
|
|
3755
3755
|
*/
|
|
3756
3756
|
async dispatchToHandlers(adapter, threadId, message, context) {
|
|
3757
|
-
|
|
3757
|
+
const hasMention = this.setMentionFlags(adapter, message, context);
|
|
3758
3758
|
const isSubscribed = await this._stateAdapter.isSubscribed(threadId);
|
|
3759
3759
|
this.logger.debug("Subscription check", {
|
|
3760
3760
|
threadId,
|
|
@@ -3814,7 +3814,7 @@ var Chat = class {
|
|
|
3814
3814
|
);
|
|
3815
3815
|
return;
|
|
3816
3816
|
}
|
|
3817
|
-
if (message.isMention) {
|
|
3817
|
+
if (message.isMention || hasMention) {
|
|
3818
3818
|
this.logger.debug("Bot mentioned", {
|
|
3819
3819
|
threadId,
|
|
3820
3820
|
text: message.text.slice(0, 100)
|
|
@@ -3850,6 +3850,15 @@ var Chat = class {
|
|
|
3850
3850
|
});
|
|
3851
3851
|
}
|
|
3852
3852
|
}
|
|
3853
|
+
setMentionFlags(adapter, message, context) {
|
|
3854
|
+
message.isMention = message.isMention || this.detectMention(adapter, message);
|
|
3855
|
+
let hasMention = message.isMention === true;
|
|
3856
|
+
for (const skipped of context?.skipped ?? []) {
|
|
3857
|
+
skipped.isMention = skipped.isMention || this.detectMention(adapter, skipped);
|
|
3858
|
+
hasMention = hasMention || skipped.isMention === true;
|
|
3859
|
+
}
|
|
3860
|
+
return hasMention;
|
|
3861
|
+
}
|
|
3853
3862
|
createThread(adapter, threadId, initialMessage, isSubscribedContext = false) {
|
|
3854
3863
|
const channelId = adapter.channelIdFromThreadId(threadId);
|
|
3855
3864
|
const isDM = adapter.isDM?.(threadId) ?? false;
|
|
@@ -4064,9 +4073,12 @@ var Plan = class {
|
|
|
4064
4073
|
return null;
|
|
4065
4074
|
}
|
|
4066
4075
|
const title = contentToPlainText(options.title) || "Task";
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4076
|
+
const autoCompletePrevious = options.autoCompletePrevious ?? true;
|
|
4077
|
+
if (autoCompletePrevious) {
|
|
4078
|
+
for (const task of this._model.tasks) {
|
|
4079
|
+
if (task.status === "in_progress") {
|
|
4080
|
+
task.status = "complete";
|
|
4081
|
+
}
|
|
4070
4082
|
}
|
|
4071
4083
|
}
|
|
4072
4084
|
const nextTask = {
|
|
@@ -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;
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
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-
|
|
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';
|
package/dist/jsx-runtime.js
CHANGED
package/docs/adapters.mdx
CHANGED
|
@@ -1,146 +1,159 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
description:
|
|
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
|
|
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
|
-
|
|
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
|
-
##
|
|
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 /> Private chat drafts / 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 | <Warn /> | <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
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
</Callout>
|
|
23
|
+
```typescript title="scripts/list-adapters.ts" lineNumbers
|
|
24
|
+
import { ADAPTER_NAMES, getAdapter } from "chat/adapters";
|
|
116
25
|
|
|
117
|
-
|
|
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
|
-
|
|
32
|
+
Use the env helpers when you need to show setup instructions or inject secrets for one adapter:
|
|
120
33
|
|
|
121
|
-
|
|
34
|
+
```typescript lineNumbers
|
|
35
|
+
import { getAdapter, getSecretEnvVars } from "chat/adapters";
|
|
122
36
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
import type { WebhookOptions } from "chat";
|
|
37
|
+
const slack = getAdapter("slack");
|
|
38
|
+
const secrets = getSecretEnvVars("slack").map((envVar) => envVar.key);
|
|
126
39
|
|
|
127
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
@@ -64,6 +64,6 @@ bot.onSubscribedMessage(async (thread) => {
|
|
|
64
64
|
|
|
65
65
|
## Resources
|
|
66
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) — 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.
|
|
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
68
|
|
|
69
|
-
See all guides and templates on the [resources](/resources) page.
|
|
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.
|
package/docs/api/cards.mdx
CHANGED
|
@@ -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',
|
package/docs/api/message.mdx
CHANGED
|
@@ -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.
|
|
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.
|
package/docs/concurrency.mdx
CHANGED
|
@@ -36,6 +36,10 @@ Chat SDK ships with Vercel-maintained adapters for Slack, Teams, Google Chat, Di
|
|
|
36
36
|
- Documentation of the adapter in primary vendor docs.
|
|
37
37
|
- Announcement of the adapter in blog post or changelog and social media.
|
|
38
38
|
|
|
39
|
+
<Callout type="info">
|
|
40
|
+
Vendor-official adapters should include a Chat SDK docs PR that adds the adapter to the vendor-official listing and the [`chat/adapters` catalog](/docs/adapters#adapter-catalog-chatadapters). Include the package name, peer dependencies, environment variables, credential modes, and any constructor-only config so setup UIs and onboarding tools can discover the adapter without importing its package.
|
|
41
|
+
</Callout>
|
|
42
|
+
|
|
39
43
|
## Project setup
|
|
40
44
|
|
|
41
45
|
This guide uses a hypothetical **Matrix** adapter as a running example. Replace "matrix" with your platform name throughout.
|
|
@@ -339,6 +343,8 @@ async handleWebhook(
|
|
|
339
343
|
|
|
340
344
|
Convert the raw platform message into a normalized `Message` instance. The `author` fields use `userId` and `userName`, and `isBot` accepts `boolean | "unknown"`. Include a `metadata` object with `dateSent` and `edited` instead of a top-level `createdAt`.
|
|
341
345
|
|
|
346
|
+
Set `author.isMe` only when the message was sent by this adapter runtime and should be ignored by Chat SDK's handler dispatch. Do not map a platform "sent from my account" flag directly to `isMe` unless that account is the bot identity. For user-owned account adapters, keep user-authored messages as `isMe: false` and track message IDs returned by `postMessage`; if the platform echoes one of those IDs through the webhook, mark that echo as `isMe: true` and `isBot: true`.
|
|
347
|
+
|
|
342
348
|
```typescript title="src/adapter.ts" lineNumbers
|
|
343
349
|
parseMessage(raw: unknown): Message<unknown> {
|
|
344
350
|
const payload = raw as Record<string, unknown>;
|