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

推荐订阅源

Y
Y Combinator Blog
有赞技术团队
有赞技术团队
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Vercel News
Vercel News
IT之家
IT之家
MyScale Blog
MyScale Blog
博客园_首页
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
罗磊的独立博客

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.