Skip to content

Commit c2badc6

Browse files
authored
docs: add agent readability improvements (#382)
* docs: add agent readability improvements - Add AGENTS.md skill file served at /AGENTS.md - Add /.well-known/agent-skills/ discovery index and SKILL.md - Add JSON-LD structured data to homepage - Exclude AGENTS.md and .well-known from i18n middleware * fix: suppress biome lint for JSON-LD dangerouslySetInnerHTML --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
1 parent bca4792 commit c2badc6

6 files changed

Lines changed: 441 additions & 12 deletions

File tree

apps/docs/app/[lang]/(home)/page.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,30 @@ const textGridSection = [
132132
},
133133
];
134134

135+
const jsonLd = {
136+
"@context": "https://schema.org",
137+
"@type": "SoftwareSourceCode",
138+
name: "Chat SDK",
139+
description: textDescription,
140+
url: "https://chat-sdk.dev",
141+
codeRepository: "https://github.com/vercel/chat",
142+
programmingLanguage: "TypeScript",
143+
runtimePlatform: "Node.js",
144+
license: "https://opensource.org/licenses/Apache-2.0",
145+
author: {
146+
"@type": "Organization",
147+
name: "Vercel",
148+
url: "https://vercel.com",
149+
},
150+
};
151+
135152
const HomePage = () => (
136153
<div className="container mx-auto max-w-5xl">
154+
<script
155+
// biome-ignore lint/security/noDangerouslySetInnerHtml: static JSON-LD, not user input
156+
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
157+
type="application/ld+json"
158+
/>
137159
<Hero
138160
badge="Chat SDK is now open source and in beta"
139161
description={heroDescription}

apps/docs/proxy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const proxy = (request: NextRequest, context: NextFetchEvent) => {
8181
export const config = {
8282
// Matcher ignoring `/_next/`, `/api/`, static assets, favicon, sitemap, robots, etc.
8383
matcher: [
84-
"/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
84+
"/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt|AGENTS.md|\\.well-known).*)",
8585
],
8686
};
8787

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
---
2+
name: chat-sdk
3+
description: Build multi-platform chat bots with Chat SDK (`chat` npm package). Use when developers want to build a Slack, Teams, Google Chat, Discord, Telegram, GitHub, Linear, or WhatsApp bot, handle mentions, direct messages, subscribed threads, reactions, slash commands, cards, modals, files, or AI streaming, set up webhook routes or multi-adapter bots, send rich cards or streamed AI responses to chat platforms, or build a custom adapter or state adapter.
4+
---
5+
6+
# Chat SDK
7+
8+
Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, Telegram, GitHub, Linear, and WhatsApp. Write bot logic once, deploy everywhere.
9+
10+
## Start with published sources
11+
12+
When Chat SDK is installed in a user project, inspect the published files that ship in `node_modules`:
13+
14+
```
15+
node_modules/chat/docs/ # bundled docs
16+
node_modules/chat/dist/index.d.ts # core API types
17+
node_modules/chat/dist/jsx-runtime.d.ts # JSX runtime types
18+
node_modules/chat/docs/contributing/ # adapter-authoring docs
19+
node_modules/chat/docs/guides/ # framework/platform guides
20+
```
21+
22+
If one of the paths below does not exist, that package is not installed in the project yet.
23+
24+
Read these before writing code:
25+
- `node_modules/chat/docs/getting-started.mdx` — install and setup
26+
- `node_modules/chat/docs/usage.mdx``Chat` config and lifecycle
27+
- `node_modules/chat/docs/handling-events.mdx` — event routing and handlers
28+
- `node_modules/chat/docs/threads-messages-channels.mdx` — thread/channel/message model
29+
- `node_modules/chat/docs/posting-messages.mdx` — post, edit, delete, schedule
30+
- `node_modules/chat/docs/streaming.mdx` — AI SDK integration and streaming semantics
31+
- `node_modules/chat/docs/cards.mdx` — JSX cards
32+
- `node_modules/chat/docs/actions.mdx` — button/select interactions
33+
- `node_modules/chat/docs/modals.mdx` — modal submit/close flows
34+
- `node_modules/chat/docs/slash-commands.mdx` — slash command routing
35+
- `node_modules/chat/docs/direct-messages.mdx` — DM behavior and `openDM()`
36+
- `node_modules/chat/docs/files.mdx` — attachments/uploads
37+
- `node_modules/chat/docs/state.mdx` — persistence, locking, dedupe
38+
- `node_modules/chat/docs/adapters.mdx` — cross-platform feature matrix
39+
- `node_modules/chat/docs/api/chat.mdx` — exact `Chat` API
40+
- `node_modules/chat/docs/api/thread.mdx` — exact `Thread` API
41+
- `node_modules/chat/docs/api/message.mdx` — exact `Message` API
42+
- `node_modules/chat/docs/api/modals.mdx` — modal element and event details
43+
44+
For the specific adapter or state package you are using, inspect that installed package's `dist/index.d.ts` export surface in `node_modules`.
45+
46+
## Quick start
47+
48+
```typescript
49+
import { Chat } from "chat";
50+
import { createSlackAdapter } from "@chat-adapter/slack";
51+
import { createRedisState } from "@chat-adapter/state-redis";
52+
53+
const bot = new Chat({
54+
userName: "mybot",
55+
adapters: {
56+
slack: createSlackAdapter(),
57+
},
58+
state: createRedisState(),
59+
dedupeTtlMs: 600_000,
60+
});
61+
62+
bot.onNewMention(async (thread) => {
63+
await thread.subscribe();
64+
await thread.post("Hello! I'm listening to this thread.");
65+
});
66+
67+
bot.onSubscribedMessage(async (thread, message) => {
68+
await thread.post(`You said: ${message.text}`);
69+
});
70+
```
71+
72+
## Core concepts
73+
74+
- **Chat** — main entry point; coordinates adapters, routing, locks, and state
75+
- **Adapters** — platform-specific integrations for Slack, Teams, Google Chat, Discord, Telegram, GitHub, Linear, and WhatsApp
76+
- **State adapters** — persistence for subscriptions, locks, dedupe, and thread state
77+
- **Thread** — conversation context with `post()`, `stream()`, `subscribe()`, `setState()`, `startTyping()`
78+
- **Message** — normalized content with `text`, `formatted`, attachments, author info, and platform `raw`
79+
- **Channel** — container for threads and top-level posts
80+
81+
## Event handlers
82+
83+
| Handler | Trigger |
84+
|---------|---------|
85+
| `onNewMention` | Bot @-mentioned in an unsubscribed thread |
86+
| `onDirectMessage` | New DM in an unsubscribed DM thread |
87+
| `onSubscribedMessage` | Any message in a subscribed thread |
88+
| `onNewMessage(regex)` | Regex match in an unsubscribed thread |
89+
| `onReaction(emojis?)` | Emoji added or removed |
90+
| `onAction(actionIds?)` | Button clicks and select/radio interactions |
91+
| `onModalSubmit(callbackId?)` | Modal form submitted |
92+
| `onModalClose(callbackId?)` | Modal dismissed/cancelled |
93+
| `onSlashCommand(commands?)` | Slash command invocation |
94+
| `onAssistantThreadStarted` | Slack assistant thread opened |
95+
| `onAssistantContextChanged` | Slack assistant context changed |
96+
| `onAppHomeOpened` | Slack App Home opened |
97+
| `onMemberJoinedChannel` | Slack member joined channel event |
98+
99+
Read `node_modules/chat/docs/handling-events.mdx`, `node_modules/chat/docs/actions.mdx`, `node_modules/chat/docs/modals.mdx`, and `node_modules/chat/docs/slash-commands.mdx` before wiring handlers. `onDirectMessage` behavior is documented in `node_modules/chat/docs/direct-messages.mdx`.
100+
101+
## Streaming
102+
103+
Pass any `AsyncIterable<string>` to `thread.post()` or `thread.stream()`. For AI SDK, prefer `result.fullStream` over `result.textStream` when available so step boundaries are preserved.
104+
105+
```typescript
106+
import { ToolLoopAgent } from "ai";
107+
108+
const agent = new ToolLoopAgent({ model: "anthropic/claude-4.5-sonnet" });
109+
110+
bot.onNewMention(async (thread, message) => {
111+
const result = await agent.stream({ prompt: message.text });
112+
await thread.post(result.fullStream);
113+
});
114+
```
115+
116+
Key details:
117+
- `streamingUpdateIntervalMs` controls post+edit fallback cadence
118+
- `fallbackStreamingPlaceholderText` defaults to `"..."`; set `null` to disable
119+
- Structured `StreamChunk` support is Slack-only; other adapters ignore non-text chunks
120+
121+
## Cards and modals (JSX)
122+
123+
Set `jsxImportSource: "chat"` in `tsconfig.json`.
124+
125+
Card components:
126+
- `Card`, `CardText`, `Section`, `Fields`, `Field`, `Button`, `CardLink`, `LinkButton`, `Actions`, `Select`, `SelectOption`, `RadioSelect`, `Table`, `Image`, `Divider`
127+
128+
Modal components:
129+
- `Modal`, `TextInput`, `Select`, `SelectOption`, `RadioSelect`
130+
131+
```tsx
132+
await thread.post(
133+
<Card title="Order #1234">
134+
<CardText>Your order has been received.</CardText>
135+
<Actions>
136+
<Button id="approve" style="primary">Approve</Button>
137+
<Button id="reject" style="danger">Reject</Button>
138+
</Actions>
139+
</Card>
140+
);
141+
```
142+
143+
## Adapter inventory
144+
145+
### Official platform adapters
146+
147+
| Platform | Package | Factory |
148+
|---------|---------|---------|
149+
| Slack | `@chat-adapter/slack` | `createSlackAdapter` |
150+
| Microsoft Teams | `@chat-adapter/teams` | `createTeamsAdapter` |
151+
| Google Chat | `@chat-adapter/gchat` | `createGoogleChatAdapter` |
152+
| Discord | `@chat-adapter/discord` | `createDiscordAdapter` |
153+
| GitHub | `@chat-adapter/github` | `createGitHubAdapter` |
154+
| Linear | `@chat-adapter/linear` | `createLinearAdapter` |
155+
| Telegram | `@chat-adapter/telegram` | `createTelegramAdapter` |
156+
| WhatsApp Business Cloud | `@chat-adapter/whatsapp` | `createWhatsAppAdapter` |
157+
158+
### Official state adapters
159+
160+
| State backend | Package | Factory |
161+
|--------------|---------|---------|
162+
| Redis | `@chat-adapter/state-redis` | `createRedisState` |
163+
| ioredis | `@chat-adapter/state-ioredis` | `createIoRedisState` |
164+
| PostgreSQL | `@chat-adapter/state-pg` | `createPostgresState` |
165+
| Memory | `@chat-adapter/state-memory` | `createMemoryState` |
166+
167+
### Community adapters
168+
169+
- `chat-state-cloudflare-do`
170+
- `@beeper/chat-adapter-matrix`
171+
- `chat-adapter-imessage`
172+
- `@bitbasti/chat-adapter-webex`
173+
- `@resend/chat-sdk-adapter`
174+
- `@zernio/chat-sdk-adapter`
175+
- `chat-adapter-baileys`
176+
- `@liveblocks/chat-sdk-adapter`
177+
- `chat-adapter-sendblue`
178+
- `chat-adapter-zalo`
179+
180+
### Coming-soon platform entries
181+
182+
- Instagram
183+
- Signal
184+
- X
185+
- Messenger
186+
187+
## Building a custom adapter
188+
189+
Read these published docs first:
190+
- `node_modules/chat/docs/contributing/building.mdx`
191+
- `node_modules/chat/docs/contributing/testing.mdx`
192+
- `node_modules/chat/docs/contributing/publishing.mdx`
193+
194+
Also inspect:
195+
- `node_modules/chat/dist/index.d.ts``Adapter` and related interfaces
196+
- `node_modules/@chat-adapter/shared/dist/index.d.ts` — shared errors and utilities
197+
- Installed official adapter `dist/index.d.ts` files — reference implementations for config and APIs
198+
199+
A custom adapter needs request verification, webhook parsing, message/thread/channel operations, ID encoding/decoding, and a format converter. Use `BaseFormatConverter` from `chat` and shared utilities from `@chat-adapter/shared`.
200+
201+
## Webhook setup
202+
203+
Each registered adapter exposes `bot.webhooks.<name>`. Wire those directly to your HTTP framework routes. See `node_modules/chat/docs/guides/slack-nextjs.mdx` and `node_modules/chat/docs/guides/discord-nuxt.mdx` for framework-specific route patterns.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"skills": [
3+
{
4+
"name": "chat-sdk",
5+
"type": "skill-md",
6+
"description": "Build multi-platform chat bots with Chat SDK (`chat` npm package). Use when developers want to build a Slack, Teams, Google Chat, Discord, Telegram, GitHub, Linear, or WhatsApp bot with a single TypeScript codebase.",
7+
"url": "/.well-known/agent-skills/chat-sdk/SKILL.md",
8+
"digest": "sha256:2a83553c6351ee766e3d58eeefa99240ac37af091b63df8844b06e893c87cdb9"
9+
}
10+
]
11+
}

0 commit comments

Comments
 (0)