PostableMessage
The union type accepted by thread.post() for sending messages.
PostableMessage is the union of all message formats accepted by thread.post() and sent.edit().
type PostableMessage =
| AdapterPostableMessage
| AsyncIterable<string | StreamChunk | StreamEvent>
| PostableObject;PostableObject covers Plan (mutable task lists) and StreamingPlan (streams with platform-specific options) — both documented below.
String
Raw text passed through as-is to the platform.
await thread.post("Hello world");PostableRaw
Explicit raw text — behaves the same as a plain string.
await thread.post({ raw: "Hello world" });Prop
Type
PostableMarkdown
Markdown converted to each platform's native format.
await thread.post({ markdown: "**Bold** and _italic_" });Prop
Type
PostableAst
mdast AST converted to each platform's native format. See Markdown for builder functions.
import { root, paragraph, text, strong } from "chat";
await thread.post({
ast: root([paragraph([strong([text("Hello")])])]),
});Prop
Type
PostableCard
Rich card with interactive elements. See Cards for components.
import { Card, Text } from "chat";
await thread.post(Card({ title: "Hello", children: [Text("World")] }));You can also pass a card with explicit fallback text:
await thread.post({
card: Card({ title: "Hello", children: [Text("World")] }),
fallbackText: "Hello — World",
});Prop
Type
Plan
A Plan is a step-by-step task list that mutates after posting. Each addTask / updateTask / complete call re-renders the same message in place. See Plan API for full usage.
import { Plan } from "chat";
const plan = new Plan({ initialMessage: "Researching options..." });
await thread.post(plan);
await plan.addTask({ title: "Look up records" });
await plan.complete({ completeMessage: "Done!" });Adapters that don't support PostableObject editing render the plan as fallback text and ignore subsequent mutations.
StreamingPlan
Wraps an async iterable with platform-specific streaming options. Use this when you need to pass options like task grouping or stop blocks through thread.post(). See Streaming with options.
import { StreamingPlan } from "chat";
const planned = new StreamingPlan(stream, {
groupTasks: "plan",
endWith: [feedbackBlock],
updateIntervalMs: 750,
});
await thread.post(planned);Prop
Type
AsyncIterable (streaming)
An async iterable of strings, StreamChunk objects, or stream events. The SDK streams the message in real time using platform-native APIs where available.
You can yield structured StreamChunk objects for rich content like task progress cards on platforms that support it (Slack). See Streaming for details.
Both AI SDK stream types are supported:
// fullStream (recommended) — preserves step boundaries in multi-step agents
const result = await agent.stream({ prompt: message.text });
await thread.post(result.fullStream);
// textStream — plain string chunks
await thread.post(result.textStream);When using fullStream, the SDK auto-detects text-delta and finish-step events, extracting text and inserting paragraph breaks between agent steps.
FileUpload
Used in the files field of any structured message format.
Prop
Type