chat 4.13.1 → 4.13.2

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 (53) hide show
  1. package/README.md +19 -31
  2. package/dist/{chunk-WKJEG4FE.js → chunk-THM4ACIE.js} +12 -4
  3. package/dist/chunk-THM4ACIE.js.map +1 -0
  4. package/dist/index.d.ts +409 -415
  5. package/dist/index.js +63 -29
  6. package/dist/index.js.map +1 -1
  7. package/dist/{jsx-runtime-COVsDskT.d.ts → jsx-runtime-Bdt1Dwzf.d.ts} +71 -71
  8. package/dist/jsx-runtime.d.ts +1 -1
  9. package/dist/jsx-runtime.js +1 -1
  10. package/docs/actions.mdx +98 -0
  11. package/docs/adapters/discord.mdx +217 -0
  12. package/docs/adapters/gchat.mdx +232 -0
  13. package/docs/adapters/github.mdx +225 -0
  14. package/docs/adapters/index.mdx +110 -0
  15. package/docs/adapters/linear.mdx +207 -0
  16. package/docs/adapters/meta.json +12 -0
  17. package/docs/adapters/slack.mdx +293 -0
  18. package/docs/adapters/teams.mdx +225 -0
  19. package/docs/api/cards.mdx +217 -0
  20. package/docs/api/channel.mdx +176 -0
  21. package/docs/api/chat.mdx +469 -0
  22. package/docs/api/index.mdx +29 -0
  23. package/docs/api/markdown.mdx +235 -0
  24. package/docs/api/message.mdx +163 -0
  25. package/docs/api/meta.json +14 -0
  26. package/docs/api/modals.mdx +222 -0
  27. package/docs/api/postable-message.mdx +166 -0
  28. package/docs/api/thread.mdx +186 -0
  29. package/docs/cards.mdx +213 -0
  30. package/docs/direct-messages.mdx +56 -0
  31. package/docs/emoji.mdx +77 -0
  32. package/docs/ephemeral-messages.mdx +77 -0
  33. package/docs/error-handling.mdx +147 -0
  34. package/docs/files.mdx +77 -0
  35. package/docs/getting-started.mdx +12 -0
  36. package/docs/guides/code-review-hono.mdx +248 -0
  37. package/docs/guides/discord-nuxt.mdx +237 -0
  38. package/docs/guides/meta.json +4 -0
  39. package/docs/guides/slack-nextjs.mdx +245 -0
  40. package/docs/index.mdx +92 -0
  41. package/docs/meta.json +20 -0
  42. package/docs/modals.mdx +208 -0
  43. package/docs/posting-messages.mdx +177 -0
  44. package/docs/slash-commands.mdx +110 -0
  45. package/docs/state/index.mdx +31 -0
  46. package/docs/state/ioredis.mdx +81 -0
  47. package/docs/state/memory.mdx +52 -0
  48. package/docs/state/meta.json +9 -0
  49. package/docs/state/redis.mdx +93 -0
  50. package/docs/streaming.mdx +99 -0
  51. package/docs/usage.mdx +338 -0
  52. package/package.json +10 -10
  53. package/dist/chunk-WKJEG4FE.js.map +0 -1
@@ -0,0 +1,237 @@
1
+ ---
2
+ title: Discord support bot with Nuxt and Redis
3
+ description: This guide walks through building a Discord support bot with Nuxt, covering project setup, Discord app configuration, Gateway forwarding, AI-powered responses, and deployment.
4
+ type: guide
5
+ prerequisites: []
6
+ related:
7
+ - /docs/adapters/discord
8
+ - /docs/cards
9
+ - /docs/actions
10
+ ---
11
+
12
+ ## Prerequisites
13
+
14
+ - Node.js 18+
15
+ - [pnpm](https://pnpm.io) (or npm/yarn)
16
+ - A Discord server where you have admin access
17
+ - A Redis instance for state management
18
+
19
+ ## Create a Nuxt app
20
+
21
+ Scaffold a new Nuxt project and install Chat SDK dependencies:
22
+
23
+ ```sh title="Terminal"
24
+ npx nuxi@latest init my-discord-bot
25
+ cd my-discord-bot
26
+ pnpm add chat @chat-adapter/discord @chat-adapter/state-redis ai @ai-sdk/anthropic
27
+ ```
28
+
29
+ ## Create a Discord app
30
+
31
+ 1. Go to [discord.com/developers/applications](https://discord.com/developers/applications)
32
+ 2. Click **New Application**, give it a name, and click **Create**
33
+ 3. Go to **Bot** in the sidebar and click **Reset Token** — copy the token, you'll need this as `DISCORD_BOT_TOKEN`
34
+ 4. Under **Privileged Gateway Intents**, enable **Message Content Intent**
35
+ 5. Go to **General Information** and copy the **Application ID** and **Public Key** — you'll need these as `DISCORD_APPLICATION_ID` and `DISCORD_PUBLIC_KEY`
36
+
37
+ ### Set up the Interactions endpoint
38
+
39
+ 1. In **General Information**, set the **Interactions Endpoint URL** to `https://your-domain.com/api/webhooks/discord`
40
+ 2. Discord will send a PING to verify the endpoint — you'll need to deploy first or use a tunnel
41
+
42
+ ### Invite the bot to your server
43
+
44
+ 1. Go to **OAuth2** in the sidebar
45
+ 2. Under **OAuth2 URL Generator**, select the `bot` scope
46
+ 3. Under **Bot Permissions**, select:
47
+ - Send Messages
48
+ - Create Public Threads
49
+ - Send Messages in Threads
50
+ - Read Message History
51
+ - Add Reactions
52
+ - Use Slash Commands
53
+ 4. Copy the generated URL and open it in your browser to invite the bot
54
+
55
+ ## Configure environment variables
56
+
57
+ Create a `.env` file in your project root:
58
+
59
+ ```bash title=".env"
60
+ DISCORD_BOT_TOKEN=your_bot_token
61
+ DISCORD_PUBLIC_KEY=your_public_key
62
+ DISCORD_APPLICATION_ID=your_application_id
63
+ REDIS_URL=redis://localhost:6379
64
+ ANTHROPIC_API_KEY=your_anthropic_api_key
65
+ ```
66
+
67
+ ## Create the bot
68
+
69
+ Create `server/lib/bot.ts` with a `Chat` instance configured with the Discord adapter. This bot uses AI SDK to answer support questions:
70
+
71
+ ```typescript title="server/lib/bot.tsx" lineNumbers
72
+ import { Chat, ConsoleLogger, Card, CardText as Text, Actions, Button, Divider } from "chat";
73
+ import { createDiscordAdapter } from "@chat-adapter/discord";
74
+ import { createRedisState } from "@chat-adapter/state-redis";
75
+ import { generateText } from "ai";
76
+ import { anthropic } from "@ai-sdk/anthropic";
77
+
78
+ const logger = new ConsoleLogger();
79
+
80
+ export const bot = new Chat({
81
+ userName: "support-bot",
82
+ adapters: {
83
+ discord: createDiscordAdapter({
84
+ botToken: process.env.DISCORD_BOT_TOKEN!,
85
+ publicKey: process.env.DISCORD_PUBLIC_KEY!,
86
+ applicationId: process.env.DISCORD_APPLICATION_ID!,
87
+ logger,
88
+ }),
89
+ },
90
+ state: createRedisState({
91
+ url: process.env.REDIS_URL!,
92
+ logger,
93
+ }),
94
+ logger,
95
+ });
96
+
97
+ bot.onNewMention(async (thread) => {
98
+ await thread.subscribe();
99
+ await thread.post(
100
+ <Card title="Support">
101
+ <Text>Hey! I'm here to help. Ask your question in this thread and I'll do my best to answer it.</Text>
102
+ <Divider />
103
+ <Actions>
104
+ <Button id="escalate" style="danger">Escalate to Human</Button>
105
+ </Actions>
106
+ </Card>
107
+ );
108
+ });
109
+
110
+ bot.onSubscribedMessage(async (thread, message) => {
111
+ await thread.startTyping();
112
+
113
+ const { text } = await generateText({
114
+ model: anthropic("claude-sonnet-4-5-20250514"),
115
+ system: "You are a friendly support bot. Answer questions concisely. If you don't know the answer, say so and suggest the user click 'Escalate to Human'.",
116
+ prompt: message.text,
117
+ });
118
+
119
+ await thread.post(text);
120
+ });
121
+
122
+ bot.onAction("escalate", async (event) => {
123
+ await event.thread.post(
124
+ `${event.user.fullName} requested human support. A team member will follow up shortly.`
125
+ );
126
+ });
127
+ ```
128
+
129
+ <Callout type="info">
130
+ The file extension must be `.tsx` (not `.ts`) when using JSX components like `Card` and `Button`. Make sure your `tsconfig.json` has `"jsx": "react-jsx"` and `"jsxImportSource": "chat"`.
131
+ </Callout>
132
+
133
+ `onNewMention` fires when a user @mentions the bot. Calling `thread.subscribe()` tells the SDK to track that thread, so subsequent messages trigger `onSubscribedMessage` where AI SDK generates a response.
134
+
135
+ ## Create the webhook route
136
+
137
+ Create a server route that handles incoming Discord webhooks:
138
+
139
+ ```typescript title="server/api/webhooks/[platform].post.ts" lineNumbers
140
+ import { bot } from "../lib/bot";
141
+
142
+ type Platform = keyof typeof bot.webhooks;
143
+
144
+ export default defineEventHandler(async (event) => {
145
+ const platform = getRouterParam(event, "platform") as Platform;
146
+
147
+ const handler = bot.webhooks[platform];
148
+ if (!handler) {
149
+ throw createError({ statusCode: 404, message: `Unknown platform: ${platform}` });
150
+ }
151
+
152
+ const request = toWebRequest(event);
153
+
154
+ return handler(request, {
155
+ waitUntil: (task) => event.waitUntil(task),
156
+ });
157
+ });
158
+ ```
159
+
160
+ This creates a `POST /api/webhooks/discord` endpoint. The `waitUntil` option ensures message processing completes after the HTTP response is sent.
161
+
162
+ ## Set up the Gateway forwarder
163
+
164
+ Discord doesn't push messages to webhooks like Slack does. Instead, messages arrive through the Gateway WebSocket. The Discord adapter includes a built-in Gateway listener that connects to the WebSocket and forwards events to your webhook endpoint.
165
+
166
+ Create a route that starts the Gateway listener:
167
+
168
+ ```typescript title="server/api/discord/gateway.get.ts" lineNumbers
169
+ import { bot } from "../../lib/bot";
170
+
171
+ export default defineEventHandler(async (event) => {
172
+ await bot.initialize();
173
+
174
+ const discord = bot.getAdapter("discord");
175
+ if (!discord) {
176
+ throw createError({ statusCode: 404, message: "Discord adapter not configured" });
177
+ }
178
+
179
+ const baseUrl = process.env.NUXT_PUBLIC_SITE_URL || "http://localhost:3000";
180
+ const webhookUrl = `${baseUrl}/api/webhooks/discord`;
181
+
182
+ const durationMs = 10 * 60 * 1000; // 10 minutes
183
+
184
+ return discord.startGatewayListener(
185
+ { waitUntil: (task: Promise<unknown>) => event.waitUntil(task) },
186
+ durationMs,
187
+ undefined,
188
+ webhookUrl,
189
+ );
190
+ });
191
+ ```
192
+
193
+ The Gateway listener connects to Discord's WebSocket, receives messages, and forwards them to your webhook endpoint for processing. In production, you'll want a cron job to restart it periodically.
194
+
195
+ ## Test locally
196
+
197
+ 1. Start your development server (`pnpm dev`)
198
+ 2. Trigger the Gateway listener by visiting `http://localhost:3000/api/discord/gateway` in your browser
199
+ 3. Expose your server with a tunnel (e.g. `ngrok http 3000`)
200
+ 4. Update the **Interactions Endpoint URL** in your Discord app settings to your tunnel URL (e.g. `https://abc123.ngrok.io/api/webhooks/discord`)
201
+ 5. @mention the bot in your Discord server — it should respond with a support card
202
+ 6. Reply in the thread — AI SDK should generate a response
203
+ 7. Click **Escalate to Human** — the bot should post an escalation message
204
+
205
+ ## Add a cron job for production
206
+
207
+ The Gateway listener runs for a fixed duration. In production, set up a cron job to restart it automatically. If you're deploying to Vercel, add a `vercel.json`:
208
+
209
+ ```json title="vercel.json"
210
+ {
211
+ "crons": [
212
+ {
213
+ "path": "/api/discord/gateway",
214
+ "schedule": "*/9 * * * *"
215
+ }
216
+ ]
217
+ }
218
+ ```
219
+
220
+ This restarts the Gateway listener every 9 minutes, ensuring continuous connectivity. Protect the endpoint with a `CRON_SECRET` environment variable in production.
221
+
222
+ ## Deploy to Vercel
223
+
224
+ Deploy your bot to Vercel:
225
+
226
+ ```sh title="Terminal"
227
+ vercel deploy
228
+ ```
229
+
230
+ After deployment, set your environment variables in the Vercel dashboard (`DISCORD_BOT_TOKEN`, `DISCORD_PUBLIC_KEY`, `DISCORD_APPLICATION_ID`, `REDIS_URL`, `ANTHROPIC_API_KEY`). Update the **Interactions Endpoint URL** in your Discord app settings to your production URL.
231
+
232
+ ## Next steps
233
+
234
+ - [Cards](/docs/cards) — Build rich interactive messages with buttons, fields, and selects
235
+ - [Actions](/docs/actions) — Handle button clicks, select menus, and other interactions
236
+ - [Streaming](/docs/streaming) — Stream AI-generated responses to chat
237
+ - [Discord adapter](/docs/adapters/discord) — Full configuration reference and Gateway setup
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Guides",
3
+ "pages": ["slack-nextjs", "code-review-hono", "discord-nuxt"]
4
+ }
@@ -0,0 +1,245 @@
1
+ ---
2
+ title: Slack bot with Next.js and Redis
3
+ description: This guide walks through building a Slack bot with Next.js, covering project setup, Slack app configuration, event handling, interactive features, and deployment.
4
+ type: guide
5
+ prerequisites: []
6
+ related:
7
+ - /docs/adapters/slack
8
+ - /docs/cards
9
+ - /docs/modals
10
+ - /docs/streaming
11
+ ---
12
+
13
+ ## Prerequisites
14
+
15
+ - Node.js 18+
16
+ - [pnpm](https://pnpm.io) (or npm/yarn)
17
+ - A Slack workspace where you can install apps
18
+ - A Redis instance for state management
19
+
20
+ ## Create a Next.js app
21
+
22
+ Scaffold a new Next.js project and install Chat SDK dependencies:
23
+
24
+ ```sh title="Terminal"
25
+ npx create-next-app@latest my-slack-bot --typescript --app
26
+ cd my-slack-bot
27
+ pnpm add chat @chat-adapter/slack @chat-adapter/state-redis
28
+ ```
29
+
30
+ ## Create a Slack app
31
+
32
+ 1. Go to [api.slack.com/apps](https://api.slack.com/apps)
33
+ 2. Click **Create New App** then **From an app manifest**
34
+ 3. Select your workspace and paste the following manifest:
35
+
36
+ ```yaml title="slack-manifest.yml"
37
+ display_information:
38
+ name: My Bot
39
+ description: A bot built with Chat SDK
40
+
41
+ features:
42
+ bot_user:
43
+ display_name: My Bot
44
+ always_online: true
45
+
46
+ oauth_config:
47
+ scopes:
48
+ bot:
49
+ - app_mentions:read
50
+ - channels:history
51
+ - channels:read
52
+ - chat:write
53
+ - groups:history
54
+ - groups:read
55
+ - im:history
56
+ - im:read
57
+ - mpim:history
58
+ - mpim:read
59
+ - reactions:read
60
+ - reactions:write
61
+ - users:read
62
+
63
+ settings:
64
+ event_subscriptions:
65
+ request_url: https://your-domain.com/api/webhooks/slack
66
+ bot_events:
67
+ - app_mention
68
+ - message.channels
69
+ - message.groups
70
+ - message.im
71
+ - message.mpim
72
+ interactivity:
73
+ is_enabled: true
74
+ request_url: https://your-domain.com/api/webhooks/slack
75
+ org_deploy_enabled: false
76
+ socket_mode_enabled: false
77
+ token_rotation_enabled: false
78
+ ```
79
+
80
+ 4. Replace `https://your-domain.com/api/webhooks/slack` with your deployed webhook URL
81
+ 5. Click **Create**
82
+
83
+ ### Get credentials
84
+
85
+ After creating the app:
86
+
87
+ 1. Go to **OAuth & Permissions**, click **Install to Workspace**, and copy the **Bot User OAuth Token** (`xoxb-...`) — you'll need this as `SLACK_BOT_TOKEN`
88
+ 2. Go to **Basic Information** → **App Credentials** and copy the **Signing Secret** — you'll need this as `SLACK_SIGNING_SECRET`
89
+
90
+ ## Configure environment variables
91
+
92
+ Create a `.env.local` file in your project root:
93
+
94
+ ```bash title=".env.local"
95
+ SLACK_BOT_TOKEN=xoxb-your-bot-token
96
+ SLACK_SIGNING_SECRET=your-signing-secret
97
+ REDIS_URL=redis://localhost:6379
98
+ ```
99
+
100
+ ## Create the bot
101
+
102
+ Create `lib/bot.ts` with a `Chat` instance configured with the Slack adapter:
103
+
104
+ ```typescript title="lib/bot.ts" lineNumbers
105
+ import { Chat } from "chat";
106
+ import { createSlackAdapter } from "@chat-adapter/slack";
107
+ import { createRedisState } from "@chat-adapter/state-redis";
108
+
109
+ export const bot = new Chat({
110
+ userName: "mybot",
111
+ adapters: {
112
+ slack: createSlackAdapter({
113
+ botToken: process.env.SLACK_BOT_TOKEN!,
114
+ signingSecret: process.env.SLACK_SIGNING_SECRET!,
115
+ logger: new ConsoleLogger(),
116
+ }),
117
+ },
118
+ state: createRedisState({
119
+ url: process.env.REDIS_URL!,
120
+ logger: new ConsoleLogger(),
121
+ }),
122
+ logger: new ConsoleLogger(),
123
+ });
124
+
125
+ // Respond when someone @mentions the bot
126
+ bot.onNewMention(async (thread) => {
127
+ await thread.subscribe();
128
+ await thread.post("Hello! I'm listening to this thread now.");
129
+ });
130
+
131
+ // Respond to follow-up messages in subscribed threads
132
+ bot.onSubscribedMessage(async (thread, message) => {
133
+ await thread.post(`You said: ${message.text}`);
134
+ });
135
+ ```
136
+
137
+ `onNewMention` fires when a user @mentions your bot. Calling `thread.subscribe()` tells the SDK to track that thread, so subsequent messages trigger `onSubscribedMessage`.
138
+
139
+ ## Create the webhook route
140
+
141
+ Create a dynamic API route that handles incoming webhooks:
142
+
143
+ ```typescript title="app/api/webhooks/[platform]/route.ts" lineNumbers
144
+ import { after } from "next/server";
145
+ import { bot } from "@/lib/bot";
146
+
147
+ type Platform = keyof typeof bot.webhooks;
148
+
149
+ export async function POST(
150
+ request: Request,
151
+ context: RouteContext<"/api/webhooks/[platform]">
152
+ ) {
153
+ const { platform } = await context.params;
154
+
155
+ const handler = bot.webhooks[platform as Platform];
156
+ if (!handler) {
157
+ return new Response(`Unknown platform: ${platform}`, { status: 404 });
158
+ }
159
+
160
+ return handler(request, {
161
+ waitUntil: (task) => after(() => task),
162
+ });
163
+ }
164
+ ```
165
+
166
+ This creates a `POST /api/webhooks/slack` endpoint. The `waitUntil` option ensures message processing completes after the HTTP response is sent — required on serverless platforms where the function would otherwise terminate before your handlers finish.
167
+
168
+ ## Test locally
169
+
170
+ 1. Start your development server (`pnpm dev`)
171
+ 2. Expose it with a tunnel (e.g. `ngrok http 3000`)
172
+ 3. Update the Slack Event Subscriptions **Request URL** to your tunnel URL
173
+ 4. Invite your bot to a Slack channel (`/invite @mybot`)
174
+ 5. @mention the bot — it should respond with "Hello! I'm listening to this thread now."
175
+ 6. Reply in the thread — it should echo your message back
176
+
177
+ ## Add interactive features
178
+
179
+ Chat SDK supports rich interactive messages using a JSX-like syntax. Update your bot to send cards with buttons:
180
+
181
+ ```typescript title="lib/bot.ts" lineNumbers
182
+ import { Chat, Card, CardText as Text, Actions, Button, Divider } from "chat";
183
+ import { createSlackAdapter } from "@chat-adapter/slack";
184
+ import { createRedisState } from "@chat-adapter/state-redis";
185
+
186
+ export const bot = new Chat({
187
+ userName: "mybot",
188
+ adapters: {
189
+ slack: createSlackAdapter({
190
+ botToken: process.env.SLACK_BOT_TOKEN!,
191
+ signingSecret: process.env.SLACK_SIGNING_SECRET!,
192
+ logger: new ConsoleLogger(),
193
+ }),
194
+ },
195
+ state: createRedisState({
196
+ url: process.env.REDIS_URL!,
197
+ logger: new ConsoleLogger(),
198
+ }),
199
+ logger: new ConsoleLogger(),
200
+ });
201
+
202
+ bot.onNewMention(async (thread) => {
203
+ await thread.subscribe();
204
+ await thread.post(
205
+ <Card title="Welcome!">
206
+ <Text>I'm now listening to this thread. Try clicking a button:</Text>
207
+ <Divider />
208
+ <Actions>
209
+ <Button id="hello" style="primary">Say Hello</Button>
210
+ <Button id="info">Show Info</Button>
211
+ </Actions>
212
+ </Card>
213
+ );
214
+ });
215
+
216
+ bot.onAction("hello", async (event) => {
217
+ await event.thread.post(`Hello, ${event.user.fullName}!`);
218
+ });
219
+
220
+ bot.onAction("info", async (event) => {
221
+ await event.thread.post(`You're on ${event.thread.adapter.name}.`);
222
+ });
223
+ ```
224
+
225
+ <Callout type="info">
226
+ The file extension must be `.tsx` (not `.ts`) when using JSX components like `Card` and `Button`. Make sure your `tsconfig.json` has `"jsx": "react-jsx"` and `"jsxImportSource": "chat"`.
227
+ </Callout>
228
+
229
+ ## Deploy to Vercel
230
+
231
+ Deploy your bot to Vercel:
232
+
233
+ ```sh title="Terminal"
234
+ vercel deploy
235
+ ```
236
+
237
+ After deployment, set your environment variables in the Vercel dashboard (`SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET`, `REDIS_URL`). If your manifest used a placeholder URL, update the **Event Subscriptions** and **Interactivity** Request URLs in your [Slack app settings](https://api.slack.com/apps) to your production URL.
238
+
239
+ ## Next steps
240
+
241
+ - [Cards](/docs/cards) — Build rich interactive messages with buttons, fields, and selects
242
+ - [Modals](/docs/modals) — Open forms and dialogs from button clicks
243
+ - [Streaming](/docs/streaming) — Stream AI-generated responses to chat
244
+ - [Actions](/docs/actions) — Handle button clicks, select menus, and other interactions
245
+ - [Slack adapter](/docs/adapters/slack) — Multi-workspace OAuth, token encryption, and full configuration reference
package/docs/index.mdx ADDED
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: Introduction
3
+ description: A unified SDK for building chat bots across Slack, Microsoft Teams, Google Chat, Discord, and more.
4
+ type: overview
5
+ ---
6
+
7
+ Chat SDK is a TypeScript library for building chat bots that work across multiple platforms with a single codebase. Write your bot logic once and deploy it to Slack, Microsoft Teams, Google Chat, Discord, GitHub, and Linear.
8
+
9
+ ## Why Chat SDK?
10
+
11
+ Building a chat bot that works across multiple platforms typically means maintaining separate codebases, learning different APIs, and handling platform-specific quirks individually. Chat SDK abstracts these differences behind a unified interface.
12
+
13
+ - **Single codebase** for all platforms
14
+ - **Type-safe** adapters and event handlers with full TypeScript support
15
+ - **Event-driven** architecture with handlers for mentions, messages, reactions, button clicks, slash commands, and modals
16
+ - **Thread subscriptions** for multi-turn conversations
17
+ - **Rich UI** with JSX cards, buttons, and modals that render natively on each platform
18
+ - **AI streaming** with first-class support for streaming LLM responses
19
+ - **Serverless-ready** with distributed state via Redis and message deduplication
20
+
21
+ ## How it works
22
+
23
+ Chat SDK has three core concepts:
24
+
25
+ 1. **Chat** — the main entry point that coordinates adapters and routes events to your handlers
26
+ 2. **Adapters** — platform-specific implementations that handle webhook parsing, message formatting, and API calls
27
+ 3. **State** — a pluggable persistence layer for thread subscriptions and distributed locking
28
+
29
+ ```typescript title="lib/bot.ts" lineNumbers
30
+ import { Chat } from "chat";
31
+ import { createSlackAdapter } from "@chat-adapter/slack";
32
+ import { createRedisState } from "@chat-adapter/state-redis";
33
+
34
+ const bot = new Chat({
35
+ userName: "mybot",
36
+ adapters: {
37
+ slack: createSlackAdapter({
38
+ botToken: process.env.SLACK_BOT_TOKEN!,
39
+ signingSecret: process.env.SLACK_SIGNING_SECRET!,
40
+ logger: new ConsoleLogger(),
41
+ }),
42
+ },
43
+ state: createRedisState({
44
+ url: process.env.REDIS_URL!,
45
+ logger: new ConsoleLogger(),
46
+ }),
47
+ logger: new ConsoleLogger(),
48
+ });
49
+
50
+ bot.onNewMention(async (thread) => {
51
+ await thread.subscribe();
52
+ await thread.post("Hello! I'm listening to this thread.");
53
+ });
54
+ ```
55
+
56
+ ## Supported platforms
57
+
58
+ | Platform | Package | Mentions | Reactions | Cards | Modals | Streaming | DMs |
59
+ |----------|---------|----------|-----------|-------|--------|-----------|-----|
60
+ | Slack | `@chat-adapter/slack` | Yes | Yes | Yes | Yes | Native | Yes |
61
+ | Microsoft Teams | `@chat-adapter/teams` | Yes | Read-only | Yes | No | Post+Edit | Yes |
62
+ | Google Chat | `@chat-adapter/gchat` | Yes | Yes | Yes | No | Post+Edit | Yes |
63
+ | Discord | `@chat-adapter/discord` | Yes | Yes | Yes | No | Post+Edit | Yes |
64
+ | GitHub | `@chat-adapter/github` | Yes | Yes | No | No | No | No |
65
+ | Linear | `@chat-adapter/linear` | Yes | Yes | No | No | No | No |
66
+
67
+ ## AI coding agent support
68
+
69
+ If you use an AI coding agent like [Claude Code](https://docs.anthropic.com/en/docs/claude-code), you can teach it about Chat SDK by installing the skill:
70
+
71
+ ```bash
72
+ npx skills add vercel/chat
73
+ ```
74
+
75
+ This gives your agent access to Chat SDK's documentation, patterns, and best practices so it can help you build bots more effectively.
76
+
77
+ ## Packages
78
+
79
+ The SDK is distributed as a set of packages you install based on your needs:
80
+
81
+ | Package | Description |
82
+ |---------|-------------|
83
+ | `chat` | Core SDK with `Chat` class, types, JSX runtime, and utilities |
84
+ | `@chat-adapter/slack` | Slack adapter |
85
+ | `@chat-adapter/teams` | Microsoft Teams adapter |
86
+ | `@chat-adapter/gchat` | Google Chat adapter |
87
+ | `@chat-adapter/discord` | Discord adapter |
88
+ | `@chat-adapter/github` | GitHub Issues adapter |
89
+ | `@chat-adapter/linear` | Linear Issues adapter |
90
+ | `@chat-adapter/state-redis` | Redis state adapter (production) |
91
+ | `@chat-adapter/state-ioredis` | ioredis state adapter (alternative) |
92
+ | `@chat-adapter/state-memory` | In-memory state adapter (development) |
package/docs/meta.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "title": "Documentation",
3
+ "pages": [
4
+ "index",
5
+ "getting-started",
6
+ "usage",
7
+ "posting-messages",
8
+ "---Features---",
9
+ "...",
10
+ "error-handling",
11
+ "---Platform Adapters---",
12
+ "...adapters",
13
+ "---State Adapters---",
14
+ "...state",
15
+ "---Guides---",
16
+ "...guides",
17
+ "---API Reference---",
18
+ "...api"
19
+ ]
20
+ }