Skip to main content
Every surface that shows an agent’s reply reads its ::: blocks with the same rules: the web widget, Lua Desktop, the mobile app, Frontline, the dashboard chat, the messaging channels, email, and voice. A reply that renders as cards in one place is read as the same blocks everywhere else; what each channel then does with a block is in the channel matrix. A message you send from code with Channels.send to SMS, Front, or a generated inbox is not read for blocks: it arrives as written. The canonical form is the one the platform teaches the model:
The rules below say which other spellings count, so a block the model writes slightly differently still renders instead of reaching the end user as raw text.

Openers

A block opens at the start of a line with ::: followed by the block name. These all open the same actions block: Text after the name on the opener line is the block’s first body line, so ::: actions - Yes followed by - No on the next line gives two entries. An opener glued to text counts only when it is a known block name at the end of the line. ::: anywhere else in a line is text, never a marker: ratio 3:::2, an ARN such as arn:aws:s3:::bucket, and `a:::b` in inline code all show as written.

Closers

A block closes at a line that holds only colons: A closer with no block open, such as a stray ::: line, is removed.

One-line blocks

A whole block can sit on one line. It ends at the first run of two or more colons after a space, and the rest of the line is read again as text that can hold more blocks:
Text before a one-line block stays on its line, and text after it continues the same line.

Missing closers

The model sometimes forgets a closer. Two rules keep the reply readable:
  • A new opener closes the open block. In ::: images … ::: actions … :::, the images block ends where ::: actions starts.
  • A block still open when the reply ends renders as if it had been closed. For actions, images, links, payment, documents, reaction, and navigate, the block keeps only its own lines, such as entries, images, or links, and any prose after them shows as normal text. A list-item or horizontal-list-item card keeps its free text as the description.
While a reply streams, a block appears once its closer arrives, and a half-written marker line is held back, so the end user never sees ::: act flash on screen.

Code

Nothing inside code is a block. A block written inside a fenced code block (``` or ~~~) or inside inline code shows as code, so you can quote the syntax in a reply:
A line that opens and closes its own triple backticks, such as ```::: actions```, is inline code, not a fence.

Text around and inside blocks

  • Line breaks: a literal \n (a backslash followed by n) in the reply becomes a line break, except inside inline code or a code block, where it stays as written.
  • Several blocks of one kind are all read. The apps show each one where it sits; the messaging channels and email merge them, so two actions blocks become one set of choices with repeats removed. See each block’s page for the channels that send only the first payment link.
  • Prose inside a block whose body is a list, such as Pick one: inside ::: actions, shows as text just before the block.
  • Unknown names: the marker lines of a block the surface doesn’t know, such as ::: summary, are removed and its body shows as normal text.
  • Each part of a message is read on its own. A reply made of several text parts never has a block that starts in one part and ends in the next.

Body rules

Each block’s page lists its fields. A few rules apply across them:

See also

  • Response formatting — which blocks exist and where each one renders
  • list-item — the card most replies start with
  • form — the one block whose body is YAML