External web link that opens in browser
Display text for the action button
URL to open when clicked
Video conferencing action with provider-specific handling
URL to join the conference
Conferencing provider for UI customization
File attachment action stored in R2
Unique identifier for the stored file
Original filename
File size in bytes
MIME type of the file
OptionalimageWidth?: number | nullIntrinsic width of the image in pixels (only for image files)
OptionalimageHeight?: number | nullIntrinsic height of the image in pixels (only for image files)
Reference to an attachment hosted by a connector's source system
Opaque identifier interpreted only by the owning connector
Display filename
File size in bytes if known
MIME type
OptionalimageWidth?: number | nullIntrinsic width of the image in pixels (only for image files)
OptionalimageHeight?: number | nullIntrinsic height of the image in pixels (only for image files)
OptionalcontentId?: string | nullContent-ID of an inline body image, without the angle brackets — the
value a cid: reference in the note's content resolves against.
Set this ONLY when the note's content still references the part (an
<img src="cid:…"> that survived quote-trimming). Plot then renders
the image in the body where the sender placed it, at its own size,
instead of appending an attachment chip.
Leave it unset for ordinary attachments. An inline part the retained
content no longer references — a signature logo left behind when a
quoted reply was trimmed — should be dropped entirely rather than
emitted with a contentId, since nothing in the body points at it.
Structured plan of operations for user approval
Human-readable summary of the plan
Operations to execute on approval
Callback invoked with (action, approved: boolean) after the user decides
Optionalapproved?: booleanThe user's decision. Set by the server when the action is delivered to the plan callback; absent on the action the twist created.
Optionalresults?: PlanOperationResult[]Per-operation execution results, same order as operations. Set by
the server when approved is true: operations are executed
server-side BEFORE the callback is invoked.
Starts a realtime conversation with the twist — spoken, typed, or both. The conversation's turns are written into the thread as notes.
Display text for the chat button
Fallback URL for clients that predate chat support. Such clients
coerce unknown action types to external and open this instead, so
it must be a working link to the thread. The runtime fills it in.
Token for the twist method that returns the session's NewChatSpec. Resolved when the user taps, not when the note was written, so a stale note still opens a current conversation.
// External action - opens URL in browser
const externalAction: Action = {
type: ActionType.external,
title: "Open in Google Calendar",
url: "https://calendar.google.com/event/123",
};
// Conferencing action - opens video conference with provider info
const conferencingAction: Action = {
type: ActionType.conferencing,
url: "https://meet.google.com/abc-defg-hij",
provider: ConferencingProvider.googleMeet,
};
// Integrations action - initiates OAuth flow
const authAction: Action = {
type: ActionType.auth,
title: "Continue with Google",
provider: AuthProvider.Google,
scopes: ["https://www.googleapis.com/auth/calendar.readonly"],
callback: "callback-token-for-auth-completion"
};
// Callback action - triggers a twist method
const callbackAction: Action = {
type: ActionType.callback,
title: "📅 Primary Calendar",
token: "callback-token-here"
};
Represents a clickable action attached to a thread.
Thread actions are rendered as buttons that enable user interaction with threads. Different action types have specific behaviors and required fields for proper functionality.