---
name: acai-ui
description: Render results as rich cards, metric tiles and follow-up buttons instead of plain prose, using Acai's acai:ui blocks.
---

# Rich UI blocks

Acai renders a fenced `acai:ui` block as native components. Emit one when it
genuinely reads better than prose — not for everything.

The JSON must be valid and on its own inside the fence. A malformed block is
shown as raw code, which looks like a mistake to the user.

## cards

For a handful of rich items: stores, products, anything with a few named fields.

````
```acai:ui
{"type": "cards", "items": [
  {"title": "Watford",
   "subtitle": "4.2 miles · cost centre 1042",
   "fields": [["Stock", "12"], ["Price", "£24.99"]],
   "status": "ok"},
  {"title": "Slough",
   "subtitle": "7.8 miles · cost centre 1081",
   "fields": [["Stock", "0"], ["Price", "£24.99"]],
   "status": "warn"}
]}
```
````

- `status` is `ok`, `warn`, `error` or `neutral` — use it for the thing that
  matters (out of stock is `warn`, not decoration).
- Up to about six cards. Beyond that use a markdown table.

### Images

Pass the URL **exactly as the tool returned it** — protocol-relative
(`//host/path`) is fine and is resolved for you. Do not rewrite, prefix or
"fix" it; a URL you compose or recall is not loaded at all, because images only
load from hosts this conversation's tool results referenced.

Give every size you have and the picture is picked to suit the space:

```json
{"title": "Barretti Tile",
 "images": [
   {"url": "//media.example/img?$smallThumbnail$", "width": 120},
   {"url": "//media.example/img?$preview$", "width": 480},
   {"url": "//media.example/img?$detail$", "width": 1200}
 ]}
```

`width` is optional — without it the first URL is used. A single card shows its
picture full width; a list of cards uses thumbnails. Force either with
`"layout": "hero"` or `"layout": "thumbnail"`.

## metrics

A row of figures — two to four, no more.

````
```acai:ui
{"type": "metrics", "items": [
  {"label": "Stock", "value": "12", "detail": "units"},
  {"label": "Price", "value": "£24.99"},
  {"label": "Change", "value": "−8%", "detail": "since June"}
]}
```
````

## buttons

Follow-up actions. Clicking one sends its label as the user's next message.

````
```acai:ui
{"type": "buttons", "items": [
  "Check nearby stores",
  "Show price history",
  "No thanks"
]}
```
````

**Write labels that stand on their own.** The label becomes the user's message,
so it has to read correctly in the transcript by itself.

- Good: `"Check nearby stores"`, `"Show price history"`
- Bad: `"Yes"`, `"Option 2"`, `"Do it"` — meaningless when read back later

Two to four buttons. They lay out in a row and stack into a column when they
don't fit. The user can always ignore them and type instead, so never say
"choose an option" or wait for a click — buttons are a shortcut, not a gate.

## When to use which

| Situation | Use |
|---|---|
| 1–6 results with a few fields each | `cards` |
| Many rows, or mostly numbers | markdown table |
| Two to four headline figures | `metrics` |
| Obvious next steps | `buttons` |
| Anything else | plain prose |

Put a sentence of prose before a block saying what it shows. A block on its own,
with no lead-in, reads as abrupt — and it's what gets quoted back in the sidebar
preview.

Never use a block for a single value: "There are 12 units at Watford" is better
than a card containing one field.
