chat 4.29.0 → 4.30.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/dist/ai/index.d.ts +3 -3
- package/dist/{chat-D9UYaaNO.d.ts → chat-BPjXsoIl.d.ts} +9 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +14 -9
- package/dist/{jsx-runtime-CFq1K_Ve.d.ts → jsx-runtime-CnDs8rPr.d.ts} +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/docs/adapters.mdx +2 -2
- package/docs/ai/index.mdx +6 -0
- package/docs/getting-started.mdx +5 -1
- package/docs/index.mdx +3 -1
- package/docs/meta.json +1 -0
- package/docs/slack-primitives.mdx +320 -0
- package/docs/streaming.mdx +1 -1
- package/package.json +1 -1
- package/resources/guides/create-a-discord-support-bot-with-nuxt-and-redis.md +5 -1
- package/resources/guides/how-to-build-a-slack-bot-with-next-js-and-redis.md +5 -1
- package/resources/guides/human-in-the-loop-with-chat-sdk-and-workflow-sdk.md +176 -0
- package/resources/guides/liveblocks-chat-sdk-ai-sdk.md +165 -0
- package/resources/guides/run-and-track-deploys-from-slack.md +7 -5
- package/resources/guides/ship-a-github-code-review-bot-with-hono-and-redis.md +5 -1
- package/resources/guides/slack-bot-vercel-blob.md +254 -0
- package/resources/guides/triage-form-submissions-with-chat-sdk.md +3 -1
- package/resources/templates.json +5 -0
package/dist/ai/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { x as Chat, w as ChannelVisibility } from '../chat-BPjXsoIl.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-BPjXsoIl.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-CnDs8rPr.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 {
|
|
3
|
+
import { n as ChatElement, g as CardElement, Q as ModalElement, $ as SelectOptionElement } from './jsx-runtime-CnDs8rPr.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
|
-
*
|
|
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
|
|
1225
|
-
*
|
|
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
|
|
@@ -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
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
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-BPjXsoIl.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-BPjXsoIl.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 {
|
|
6
|
-
export {
|
|
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-CnDs8rPr.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-CnDs8rPr.js';
|
|
7
7
|
import '@workflow/serde';
|
|
8
8
|
|
|
9
9
|
/**
|
package/dist/index.js
CHANGED
|
@@ -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 = {
|
|
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
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
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]: () => {
|
|
@@ -779,4 +779,4 @@ declare namespace JSX {
|
|
|
779
779
|
}
|
|
780
780
|
}
|
|
781
781
|
|
|
782
|
-
export { type
|
|
782
|
+
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 };
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { A as ActionsComponent, B as ButtonComponent,
|
|
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-CnDs8rPr.js';
|
package/docs/adapters.mdx
CHANGED
|
@@ -23,7 +23,7 @@ Ready to build your own? Follow the [building](/docs/contributing/building) guid
|
|
|
23
23
|
| Edit message | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Partial | <Cross /> | <Cross /> |
|
|
24
24
|
| Delete message | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Warn /> Partial | <Cross /> | <Cross /> |
|
|
25
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 |
|
|
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
27
|
| Scheduled messages | <Check /> Native | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
|
|
28
28
|
|
|
29
29
|
### Rich content
|
|
@@ -47,7 +47,7 @@ Ready to build your own? Follow the [building](/docs/contributing/building) guid
|
|
|
47
47
|
| Mentions | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Check /> |
|
|
48
48
|
| Add reactions | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
|
|
49
49
|
| Remove reactions | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> | <Warn /> | <Warn /> | <Check /> | <Cross /> |
|
|
50
|
-
| Typing indicator | <Check /> | <Check /> | <Cross /> | <Check /> | <Check /> | <Cross /> | <Warn /> Agent sessions | <
|
|
50
|
+
| Typing indicator | <Check /> | <Check /> | <Cross /> | <Check /> | <Check /> | <Cross /> | <Warn /> Agent sessions | <Warn /> | <Check /> |
|
|
51
51
|
| DMs | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Check /> | <Check /> |
|
|
52
52
|
| Ephemeral messages | <Check /> Native | <Cross /> | <Check /> Native | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
|
|
53
53
|
| User lookup ([`getUser`](/docs/api/chat#getuser)) | <Check /> | <Warn /> Cached | <Warn /> Cached | <Check /> | <Warn /> Seen users | <Check /> | <Check /> | <Cross /> | <Cross /> |
|
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) — 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) page.
|
package/docs/getting-started.mdx
CHANGED
|
@@ -25,4 +25,8 @@ Connect your bot to chat platforms and persist state across restarts.
|
|
|
25
25
|
|
|
26
26
|
Browse all official and community adapters on the [Adapters](/adapters) page.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## Resources
|
|
29
|
+
|
|
30
|
+
- [The Complete Guide to Chat SDK](https://vercel.com/kb/guide/the-complete-guide-to-chat-sdk) — End-to-end walkthrough that takes you from zero to a deployed multi-platform bot, covering adapters, state, handlers, cards, and streaming.
|
|
31
|
+
|
|
32
|
+
See all guides and templates on the [resources](/resources) page.
|
package/docs/index.mdx
CHANGED
|
@@ -55,10 +55,11 @@ Each adapter factory auto-detects credentials from environment variables (`SLACK
|
|
|
55
55
|
| Microsoft Teams | `@chat-adapter/teams` | Yes | Read-only | Yes | Yes | Native (DMs) / Buffered | Yes |
|
|
56
56
|
| Google Chat | `@chat-adapter/gchat` | Yes | Yes | Yes | No | Post+Edit | Yes |
|
|
57
57
|
| Discord | `@chat-adapter/discord` | Yes | Yes | Yes | No | Post+Edit | Yes |
|
|
58
|
-
| Telegram | `@chat-adapter/telegram` | Yes | Yes | Partial | No | Post+Edit | Yes |
|
|
58
|
+
| Telegram | `@chat-adapter/telegram` | Yes | Yes | Partial | No | Private chat drafts / Post+Edit | Yes |
|
|
59
59
|
| GitHub | `@chat-adapter/github` | Yes | Yes | No | No | Buffered | No |
|
|
60
60
|
| Linear | `@chat-adapter/linear` | Yes | Yes | No | No | Agent sessions / Post+Edit | No |
|
|
61
61
|
| WhatsApp | `@chat-adapter/whatsapp` | N/A | Yes | Partial | No | Buffered | Yes |
|
|
62
|
+
| Twilio | `@chat-adapter/twilio` | N/A | No | Fallback | No | Buffered | Yes |
|
|
62
63
|
| Messenger | `@chat-adapter/messenger` | Yes | Receive-only | Partial | No | Buffered | Yes |
|
|
63
64
|
|
|
64
65
|
## AI coding agent support
|
|
@@ -87,6 +88,7 @@ The SDK is distributed as a set of packages you install based on your needs:
|
|
|
87
88
|
| `@chat-adapter/github` | GitHub Issues adapter |
|
|
88
89
|
| `@chat-adapter/linear` | Linear Issues adapter |
|
|
89
90
|
| `@chat-adapter/whatsapp` | WhatsApp Business adapter |
|
|
91
|
+
| `@chat-adapter/twilio` | Twilio SMS and MMS adapter |
|
|
90
92
|
| `@chat-adapter/messenger` | Facebook Messenger adapter |
|
|
91
93
|
| `@chat-adapter/state-redis` | Redis state adapter (production) |
|
|
92
94
|
| `@chat-adapter/state-ioredis` | ioredis state adapter (alternative) |
|
package/docs/meta.json
CHANGED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Slack Low-Level APIs
|
|
3
|
+
description: Use Slack request verification, formatting, Web API, and Block Kit helpers without the full Chat runtime.
|
|
4
|
+
type: guide
|
|
5
|
+
prerequisites:
|
|
6
|
+
- /adapters/official/slack
|
|
7
|
+
related:
|
|
8
|
+
- /docs/handling-events
|
|
9
|
+
- /docs/cards
|
|
10
|
+
- /docs/slash-commands
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
The Slack adapter is the right default for most bots. It verifies requests, resolves tokens, parses Slack payloads, stores thread state, and routes events through `Chat`.
|
|
14
|
+
|
|
15
|
+
Use the low-level Slack subpaths when your app already owns routing, state, sessions, or workflow execution and only needs the Slack-specific primitives.
|
|
16
|
+
|
|
17
|
+
| Subpath | Use for |
|
|
18
|
+
|---------|---------|
|
|
19
|
+
| `@chat-adapter/slack/webhook` | Request verification, body parsing, Events API payloads, slash commands, interactions, and continuation data |
|
|
20
|
+
| `@chat-adapter/slack/format` | Slack mrkdwn tokens, text objects, dates, links, mentions, and simple mrkdwn to Markdown conversion |
|
|
21
|
+
| `@chat-adapter/slack/api` | Fetch-based Slack Web API calls, thread replies, views, and files without `@slack/web-api` |
|
|
22
|
+
| `@chat-adapter/slack/blocks` | Runtime-free conversion from simple card objects and input requests to Slack Block Kit |
|
|
23
|
+
|
|
24
|
+
<Callout type="info">
|
|
25
|
+
These subpaths are for custom runtimes. If you want Chat SDK to handle webhook routing, state, subscriptions, and platform normalization, use `createSlackAdapter` from `@chat-adapter/slack`.
|
|
26
|
+
</Callout>
|
|
27
|
+
|
|
28
|
+
## Webhooks
|
|
29
|
+
|
|
30
|
+
[Slack signs incoming HTTP requests](https://docs.slack.dev/authentication/verifying-requests-from-slack/) with `x-slack-signature` and `x-slack-request-timestamp`. `verifySlackRequest` reads the request body, verifies the signature with your signing secret, and returns the raw body so you can parse it once.
|
|
31
|
+
|
|
32
|
+
```typescript title="app/api/slack/route.ts" lineNumbers
|
|
33
|
+
import {
|
|
34
|
+
parseSlackWebhookBody,
|
|
35
|
+
verifySlackRequest,
|
|
36
|
+
} from "@chat-adapter/slack/webhook";
|
|
37
|
+
import { postSlackMessage } from "@chat-adapter/slack/api";
|
|
38
|
+
|
|
39
|
+
export async function POST(request: Request) {
|
|
40
|
+
const body = await verifySlackRequest(request, {
|
|
41
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET!,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const payload = parseSlackWebhookBody(body, {
|
|
45
|
+
contentType: request.headers.get("content-type"),
|
|
46
|
+
headers: request.headers,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (payload.kind === "url_verification") {
|
|
50
|
+
return Response.json({ challenge: payload.challenge });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (payload.kind === "app_mention") {
|
|
54
|
+
await postSlackMessage({
|
|
55
|
+
channel: payload.continuation.channelId,
|
|
56
|
+
markdownText: `received: ${payload.text}`,
|
|
57
|
+
threadTs: payload.continuation.threadTs,
|
|
58
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return new Response(null, { status: 200 });
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
[Slack slash commands](https://docs.slack.dev/interactivity/implementing-slash-commands/) and interactions should be acknowledged quickly. Slack documents a 3000 ms acknowledgement window for slash commands, so do slow work in your queue or workflow runtime after returning a 2xx response.
|
|
67
|
+
|
|
68
|
+
If you do not need direct access to the verified raw body, `readSlackWebhook` combines verification and parsing:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { readSlackWebhook } from "@chat-adapter/slack/webhook";
|
|
72
|
+
|
|
73
|
+
const payload = await readSlackWebhook(request, {
|
|
74
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET!,
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If your framework already buffered the request body, use `verifySlackSignature` with the raw body and headers, then pass that same body to `parseSlackWebhookBody`.
|
|
79
|
+
|
|
80
|
+
### Payloads
|
|
81
|
+
|
|
82
|
+
`parseSlackWebhookBody` returns typed payloads:
|
|
83
|
+
|
|
84
|
+
| Kind | Slack surface |
|
|
85
|
+
|------|---------------|
|
|
86
|
+
| `url_verification` | Events API URL verification |
|
|
87
|
+
| `app_mention` | App mention events |
|
|
88
|
+
| `direct_message` | Direct message events |
|
|
89
|
+
| `slash_command` | Slash command form posts |
|
|
90
|
+
| `block_actions` | Button, select, and Block Kit action payloads |
|
|
91
|
+
| `block_suggestion` | External select suggestion payloads |
|
|
92
|
+
| `view_submission` | Modal submissions |
|
|
93
|
+
| `view_closed` | Modal close events |
|
|
94
|
+
| `unsupported` | Valid Slack payloads not normalized by this helper yet |
|
|
95
|
+
|
|
96
|
+
Message-like payloads include `continuation`, which contains provider-native reply context:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
type SlackContinuation = {
|
|
100
|
+
channelId: string;
|
|
101
|
+
enterpriseId?: string;
|
|
102
|
+
teamId?: string;
|
|
103
|
+
threadTs: string;
|
|
104
|
+
};
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This is not a Chat SDK `Thread`. It is the durable Slack data you need to reply later with `@chat-adapter/slack/api`.
|
|
108
|
+
|
|
109
|
+
App mention and direct message payloads also include typed `files` parsed from Slack file objects. Each file keeps the raw Slack object plus common fields like `id`, `name`, `mimeType`, `size`, `url`, and `downloadUrl`.
|
|
110
|
+
|
|
111
|
+
Interaction payloads expose convenience fields from Slack's raw payload:
|
|
112
|
+
|
|
113
|
+
- `block_actions` includes `actions`, `messageBlocks`, `messagePromptBlock`, `messagePromptText`, `messageTs`, `triggerId`, `responseUrl`, `user`, and `continuation`
|
|
114
|
+
- `view_submission` includes `callbackId`, `privateMetadata`, `values`, `responseUrls`, and `user`
|
|
115
|
+
|
|
116
|
+
## Formatting
|
|
117
|
+
|
|
118
|
+
Slack uses mrkdwn and special tokens for mentions, channels, dates, and links. The format subpath gives you small helpers for those strings.
|
|
119
|
+
|
|
120
|
+
The helper surface includes `escapeSlackText`, `unescapeSlackText`, `createSlackPlainText`, `createSlackMrkdwn`, `formatSlackUser`, `formatSlackChannel`, `formatSlackUserGroup`, `formatSlackSpecialMention`, `formatSlackLink`, `formatSlackDate`, and simple mrkdwn to Markdown normalization.
|
|
121
|
+
|
|
122
|
+
```typescript title="format.ts" lineNumbers
|
|
123
|
+
import {
|
|
124
|
+
createSlackMrkdwn,
|
|
125
|
+
formatSlackDate,
|
|
126
|
+
formatSlackLink,
|
|
127
|
+
formatSlackUser,
|
|
128
|
+
slackMrkdwnToMarkdown,
|
|
129
|
+
} from "@chat-adapter/slack/format";
|
|
130
|
+
|
|
131
|
+
const text = createSlackMrkdwn(
|
|
132
|
+
`${formatSlackUser("U123")} approved ${formatSlackLink("https://example.com", "the deploy")}`
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const when = formatSlackDate(
|
|
136
|
+
new Date("2026-05-27T12:00:00Z"),
|
|
137
|
+
"{date_short_pretty} at {time}",
|
|
138
|
+
"May 27 at 12:00"
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const markdown = slackMrkdwnToMarkdown("hello <@U123|jane>, see <https://example.com|this>");
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`linkBareSlackMentions` only links Slack user IDs like `@U123`. It does not resolve display names, because Slack mentions are ID-based.
|
|
145
|
+
|
|
146
|
+
## Web API
|
|
147
|
+
|
|
148
|
+
The API subpath calls [Slack Web API](https://docs.slack.dev/apis/web-api/) methods with `fetch`. It does not import `@slack/web-api`.
|
|
149
|
+
|
|
150
|
+
```typescript title="slack.ts" lineNumbers
|
|
151
|
+
import {
|
|
152
|
+
postSlackMessage,
|
|
153
|
+
sendSlackResponseUrl,
|
|
154
|
+
updateSlackMessage,
|
|
155
|
+
} from "@chat-adapter/slack/api";
|
|
156
|
+
|
|
157
|
+
const posted = await postSlackMessage({
|
|
158
|
+
channel: "C123",
|
|
159
|
+
markdownText: "**hello**",
|
|
160
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
await updateSlackMessage({
|
|
164
|
+
channel: "C123",
|
|
165
|
+
text: "updated",
|
|
166
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
167
|
+
ts: posted.id,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
await sendSlackResponseUrl("https://hooks.slack.com/actions/T/1/abc", {
|
|
171
|
+
replaceOriginal: true,
|
|
172
|
+
text: "done",
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Use `callSlackApi` when you need a Slack method that does not have a helper yet:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { callSlackApi } from "@chat-adapter/slack/api";
|
|
180
|
+
|
|
181
|
+
const result = await callSlackApi(
|
|
182
|
+
"reactions.add",
|
|
183
|
+
{ channel: "C123", name: "white_check_mark", timestamp: "1710000000.000001" },
|
|
184
|
+
{ token: process.env.SLACK_BOT_TOKEN! }
|
|
185
|
+
);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`markdownText` maps to the `markdown_text` field on [`chat.postMessage`](https://docs.slack.dev/reference/methods/chat.postMessage/) and cannot be combined with `text` or `blocks`. Use `text` with `blocks` when you need fallback text.
|
|
189
|
+
|
|
190
|
+
The subpath also includes `postSlackEphemeral`, `deleteSlackMessage`, `resolveSlackBotToken`, `encodeSlackApiBody`, and `assertSlackOk`.
|
|
191
|
+
|
|
192
|
+
Use `fetchSlackThreadReplies` when a custom runtime needs to refresh a thread with [`conversations.replies`](https://docs.slack.dev/reference/methods/conversations.replies/):
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { fetchSlackThreadReplies } from "@chat-adapter/slack/api";
|
|
196
|
+
|
|
197
|
+
const replies = await fetchSlackThreadReplies({
|
|
198
|
+
channel: payload.continuation.channelId,
|
|
199
|
+
limit: 50,
|
|
200
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
201
|
+
ts: payload.continuation.threadTs,
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Use `openSlackView` to open a modal from an interaction `trigger_id`:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { openSlackView } from "@chat-adapter/slack/api";
|
|
209
|
+
|
|
210
|
+
await openSlackView({
|
|
211
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
212
|
+
triggerId: payload.triggerId,
|
|
213
|
+
view: {
|
|
214
|
+
type: "modal",
|
|
215
|
+
title: { type: "plain_text", text: "Answer" },
|
|
216
|
+
blocks: [],
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Files
|
|
222
|
+
|
|
223
|
+
[Slack's current external upload flow](https://docs.slack.dev/changelog/2024-04-a-better-way-to-upload-files-is-here-to-stay) uses `files.getUploadURLExternal`, then uploads bytes to the returned URL, then calls `files.completeUploadExternal`.
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { uploadSlackFiles } from "@chat-adapter/slack/api";
|
|
227
|
+
|
|
228
|
+
await uploadSlackFiles(
|
|
229
|
+
[{ data: new Uint8Array([1, 2, 3]), filename: "report.txt" }],
|
|
230
|
+
{
|
|
231
|
+
channelId: "C123",
|
|
232
|
+
initialComment: "report attached",
|
|
233
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Use `fetchSlackFile` for private Slack file URLs that require bearer token authorization.
|
|
239
|
+
|
|
240
|
+
## Blocks
|
|
241
|
+
|
|
242
|
+
The blocks subpath converts simple card objects into Slack Block Kit without importing the full `chat` JSX runtime.
|
|
243
|
+
|
|
244
|
+
It exports `cardToSlackBlocks`, `cardToBlockKit`, `cardToSlackFallbackText`, `cardToFallbackText`, and `convertSlackEmojiPlaceholders`.
|
|
245
|
+
|
|
246
|
+
```typescript title="blocks.ts" lineNumbers
|
|
247
|
+
import {
|
|
248
|
+
cardToSlackBlocks,
|
|
249
|
+
cardToSlackFallbackText,
|
|
250
|
+
} from "@chat-adapter/slack/blocks";
|
|
251
|
+
import { postSlackMessage } from "@chat-adapter/slack/api";
|
|
252
|
+
|
|
253
|
+
const card = {
|
|
254
|
+
children: [
|
|
255
|
+
{ content: "deploy v2.4.1?", type: "text" },
|
|
256
|
+
{
|
|
257
|
+
children: [
|
|
258
|
+
{ id: "approve", label: "Approve", style: "primary", type: "button" },
|
|
259
|
+
{ id: "deny", label: "Deny", style: "danger", type: "button" },
|
|
260
|
+
],
|
|
261
|
+
type: "actions",
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
title: "Deployment",
|
|
265
|
+
type: "card",
|
|
266
|
+
} as const;
|
|
267
|
+
|
|
268
|
+
await postSlackMessage({
|
|
269
|
+
blocks: cardToSlackBlocks(card),
|
|
270
|
+
channel: "C123",
|
|
271
|
+
text: cardToSlackFallbackText(card),
|
|
272
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Use the full Chat SDK card JSX when you want cross-platform rendering. Use `@chat-adapter/slack/blocks` when you are building a Slack-only runtime and want Block Kit output directly.
|
|
277
|
+
|
|
278
|
+
The blocks subpath also includes small input request helpers for Slack-only runtimes:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import {
|
|
282
|
+
inputRequestToSlackBlocks,
|
|
283
|
+
parseSlackInputResponse,
|
|
284
|
+
} from "@chat-adapter/slack/blocks";
|
|
285
|
+
import { postSlackMessage } from "@chat-adapter/slack/api";
|
|
286
|
+
|
|
287
|
+
await postSlackMessage({
|
|
288
|
+
blocks: inputRequestToSlackBlocks({
|
|
289
|
+
options: [
|
|
290
|
+
{ id: "approve", label: "Approve", style: "primary" },
|
|
291
|
+
{ id: "deny", label: "Deny", style: "danger" },
|
|
292
|
+
],
|
|
293
|
+
prompt: "Approve deploy?",
|
|
294
|
+
requestId: "deploy-1",
|
|
295
|
+
}),
|
|
296
|
+
channel: "C123",
|
|
297
|
+
text: "Approve deploy?",
|
|
298
|
+
token: process.env.SLACK_BOT_TOKEN!,
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
if (payload.kind === "block_actions") {
|
|
302
|
+
const action = payload.actions[0];
|
|
303
|
+
const response = action ? parseSlackInputResponse(action) : null;
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Set `display: "radio"` for radio buttons, or `display: "select"` for a static select menu. Set `allowFreeform: true` to add a "Type your answer" button next to the provided options.
|
|
308
|
+
|
|
309
|
+
For freeform answers, use `buildSlackFreeformView` with `openSlackView`, then read the submitted value from `payload.values` with `parseSlackFreeformValue`.
|
|
310
|
+
|
|
311
|
+
## Import boundaries
|
|
312
|
+
|
|
313
|
+
The low-level Slack subpaths are designed to avoid the full runtime import graph:
|
|
314
|
+
|
|
315
|
+
- no `chat` import
|
|
316
|
+
- no `@chat-adapter/shared` import
|
|
317
|
+
- no `@slack/web-api` import
|
|
318
|
+
- no `@slack/socket-mode` import
|
|
319
|
+
|
|
320
|
+
The package still installs the full Slack adapter dependencies. The subpaths keep your source and bundle imports clean, but they are not a package-size split.
|
package/docs/streaming.mdx
CHANGED
|
@@ -59,10 +59,10 @@ await thread.post(stream);
|
|
|
59
59
|
| Platform | Method | Description |
|
|
60
60
|
|----------|--------|-------------|
|
|
61
61
|
| Slack | Native streaming API | Uses Slack's `chatStream` for smooth, real-time updates |
|
|
62
|
+
| Telegram | Private chat draft previews | Uses Telegram's `sendMessageDraft` in private chats and falls back to post + edit elsewhere |
|
|
62
63
|
| Teams | Native (DMs) / Buffered (group chats) | Uses the Teams SDK's native `stream.emit()` for direct messages; accumulates chunks and posts one final message when no native streamer is active |
|
|
63
64
|
| Google Chat | Post + Edit | Posts a message then edits it as chunks arrive |
|
|
64
65
|
| Discord | Post + Edit | Posts a message then edits it as chunks arrive |
|
|
65
|
-
| Telegram | Post + Edit | Posts a message then edits it as chunks arrive |
|
|
66
66
|
| GitHub | Buffered | Accumulates chunks and posts one final comment |
|
|
67
67
|
| Linear | Agent sessions / Post + Edit | Uses agent session activities in agent-session threads; falls back to post+edit comments in issue threads |
|
|
68
68
|
| WhatsApp | Buffered | Accumulates chunks and sends one final message |
|
package/package.json
CHANGED
|
@@ -39,7 +39,7 @@ Create a new Nuxt app and add the Chat SDK, AI SDK, and adapter packages:
|
|
|
39
39
|
|
|
40
40
|
`npx nuxi@latest init my-discord-bot cd my-discord-bot pnpm add chat @chat-adapter/discord @chat-adapter/state-redis ai @ai-sdk/anthropic`
|
|
41
41
|
|
|
42
|
-
The `chat` package is the Chat SDK core. The `@chat-adapter/discord` and `@chat-adapter/state-redis` packages are the [Discord platform adapter](https://chat-sdk.dev/adapters/discord) and [Redis state adapter](https://chat-sdk.dev/adapters/redis). The `ai` and `@ai-sdk/anthropic` packages are used to generate responses with Claude.
|
|
42
|
+
The `chat` package is the Chat SDK core. The `@chat-adapter/discord` and `@chat-adapter/state-redis` packages are the [Discord platform adapter](https://chat-sdk.dev/adapters/official/discord) and [Redis state adapter](https://chat-sdk.dev/adapters/official/redis). The `ai` and `@ai-sdk/anthropic` packages are used to generate responses with Claude.
|
|
43
43
|
|
|
44
44
|
### 2\. Create a Discord app
|
|
45
45
|
|
|
@@ -175,6 +175,10 @@ The listener runs for a fixed duration (10 minutes in this guide) and must be re
|
|
|
175
175
|
|
|
176
176
|
Verify that `REDIS_URL` is reachable from your deployment environment. The state adapter uses Redis for distributed locking, so the bot won't process messages without a working connection.
|
|
177
177
|
|
|
178
|
+
* * *
|
|
179
|
+
|
|
180
|
+
## Build with a template or read more.
|
|
181
|
+
|
|
178
182
|
---
|
|
179
183
|
|
|
180
184
|
[View full KB sitemap](/kb/sitemap.md)
|