惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
宝玉的分享
宝玉的分享
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
IT之家
IT之家
博客园_首页
博客园 - 三生石上(FineUI控件)
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
量子位
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
美团技术团队
小众软件
小众软件
Jina AI
Jina AI
S
SegmentFault 最新的问题
博客园 - Franky
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

Chat SDK Documentation

History | Chat SDK History | Chat SDK List a vendor-official adapter | Chat SDK Approvals | Chat SDK Vercel Connect | Chat SDK Teams Low-Level APIs | Chat SDK CLI | Chat SDK Platform Adapters | Chat SDK State Adapters | Chat SDK Cards | Chat SDK Getting Started | Chat SDK Introduction | Chat SDK Modals | Chat SDK Slack Low-Level APIs | Chat SDK Streaming | Chat SDK Testing | Chat SDK Overview | Chat SDK toAiMessages | Chat SDK Cards | Chat SDK Overview | Chat SDK Markdown | Chat SDK Modals | Chat SDK AI SDK Tools | Chat SDK Types | Chat SDK Message Subject | Chat SDK Conversation History | Chat SDK Transcripts | Chat SDK Slack bot with Next.js and Redis Actions | Chat SDK Direct Messages | Chat SDK
Thread | Chat SDK
Vercel · 2026-04-06 · via Chat SDK Documentation

Represents a conversation thread with methods for posting, subscribing, and state management.

A Thread is provided to your event handlers and represents a conversation thread on any platform. You can also create thread handles directly using chat.thread() or chat.openDM().

post

Post a message to the thread. Accepts strings, structured messages, cards, streams, and PostableObject instances (Plan, StreamingPlan).

// Plain text
await thread.post("Hello!");

// Markdown
await thread.post({ markdown: "**Bold** text" });

// AST
await thread.post({ ast: root([paragraph([text("Hello")])]) });

// Card
await thread.post(Card({ title: "Hi", children: [Text("Hello")] }));

// Stream (fullStream recommended for multi-step agents)
await thread.post(result.fullStream);

// Plan (mutable task list)
const plan = new Plan({ initialMessage: "Working..." });
await thread.post(plan);
await plan.addTask({ title: "Step 1" });

// Streaming with platform options
await thread.post(new StreamingPlan(stream, { groupTasks: "plan" }));

Parameters: message: string | PostableMessage | CardJSXElement

Returns: Promise<SentMessage | PostableObject> — for plain messages and streams, a SentMessage with edit(), delete(), addReaction(), and removeReaction() methods; for Plan / StreamingPlan inputs, the same object is returned so you can keep mutating it.

See Posting Messages for details on each format.

postEphemeral

Post a message visible only to a specific user.

await thread.postEphemeral(userId, "Only you can see this", {
  fallbackToDM: true,
});

Returns: Promise<EphemeralMessage | null>

Schedule a message for future delivery. Currently only supported by the Slack adapter — other adapters throw NotImplementedError.

const scheduled = await thread.schedule("Reminder: standup in 5 minutes!", {
  postAt: new Date("2026-03-09T09:00:00Z"),
});

// Cancel before it's sent
await scheduled.cancel();

Parameters: message: string | PostableMessage | CardJSXElement, options: { postAt: Date }

Returns: Promise<ScheduledMessage>

Streaming and file uploads are not supported in scheduled messages.

Get the unique human participants in a thread. Returns deduplicated authors, excluding all bots. Useful for subscribing only to 1:1 conversations and unsubscribing when others join.

const participants = await thread.getParticipants();

// Subscribe only when one person is talking to the bot
if (participants.length === 1) {
  await thread.subscribe();
}

// Unsubscribe when the thread becomes a group conversation
if (participants.length > 1) {
  await thread.unsubscribe();
}

Each call fetches the full message history to find all participants. On threads with long history this makes multiple API calls to the platform. Consider checking message.author against a known set before calling getParticipants() on every incoming message.

Manage thread subscriptions. Subscribed non-DM threads route all messages to onSubscribedMessage handlers. DM threads route to onDirectMessage first when a direct message handler is registered.

await thread.subscribe();
await thread.unsubscribe();
const subscribed = await thread.isSubscribed();

Subscriptions persist across restarts via your state adapter.

Store typed, per-thread state that persists across requests. State has a 30-day TTL.

// Read state
const state = await thread.state; // TState | null

// Merge into existing state
await thread.setState({ aiMode: true });

// Replace state entirely
await thread.setState({ aiMode: false }, { replace: true });

Show a typing indicator in the thread. No-op on platforms that don't support it. On Slack, you can pass an optional status string to show a custom loading message (requires assistant:write scope).

await thread.startTyping();

// With custom status (Slack only)
await thread.startTyping("Searching documents...");

Iterate through message history.

// Newest first (auto-paginates)
for await (const msg of thread.messages) {
  console.log(msg.text);
}

// Oldest first (auto-paginates)
for await (const msg of thread.allMessages) {
  console.log(msg.text);
}

Re-fetch messages from the API and update recentMessages.

Get a platform-specific @-mention string for a user.

await thread.post(`Hey ${thread.mentionUser(userId)}, check this out!`);

Threads can be serialized for workflow engines and external systems. The serialized thread includes the current message if one is available.

// Serialize
const json = thread.toJSON();

// Pass to a workflow
await workflow.start("my-workflow", {
  thread: thread.toJSON(),
});

The serialized format includes the thread ID, channel ID, adapter name, DM status, and the current message (if present).

Deserialization

Use bot.reviver() as a JSON.parse reviver to automatically restore Thread and Message objects from serialized payloads:

const data = JSON.parse(payload, bot.reviver());
await data.thread.post("Hello from workflow!");

Under the hood, the reviver calls ThreadImpl.fromJSON() and Message.fromJSON() for any serialized objects it encounters.

Returned by thread.schedule() and channel.schedule().

Returned by thread.post(). Extends Message with mutation methods.