Every handler (onMessage, onReaction, a tool, a JSX onClick) gets a
thread. It is the conversation: post to it, run the agent, read history,
persist state.
Not every platform supports every method (reactions, ephemeral messages,
titles, reading history). Those methods return { ok: false } or undefined
on a surface that does not support them, rather than throwing. Check the
result when it matters.
Post a message only user sees. fallbackToDM: true DMs the user where ephemeral is unsupported; false resolves null.
const ref = await thread.post("working on it...");await thread.update(ref, "done.");await thread.delete(ref);// stream text in as it is producedawait thread.stream(tokenStream);// a reply only the caller seesawait thread.postEphemeral(message.user, "psst, only you see this", { fallbackToDM: true,});// escape hatch: a raw, platform-native payload (e.g. Slack Block Kit)await thread.post({ raw: [{ type: "divider" }] });
post and update accept a raw payload as an escape hatch when a component
does not cover what a platform can do. See the UI
library.
A user message to inject. Use the array form for files and images.
context
ContextEntry[]
Extra context for this run.
tools
ChannelTool[]
Extra tools for this run.
transcript
boolean | { limit?: number }
Bridge cross-platform history for this run. See Transcripts.
// inject a prompt plus per-turn contextawait thread.runAgent({ prompt: message.text, context: [{ description: "Requesting user", value: message.user.name ?? "" }],});// resume a run that paused for a human answerawait thread.resume({ approved: true });