> ## Documentation Index
> Fetch the complete documentation index at: https://sidenet.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Rich UI components

> The nine display components, how an agent places them inside its answer, and how to stop it falling back to markdown.

An answer about revenue should be a chart, not a paragraph of numbers. Rich UI
components let an agent answer with a chart, a table, KPI cards, code, an
image or a link card, rendered natively by the chat widget instead of
approximated in markdown.

## The nine components

Each component is a tool. The agent calls it with a complete payload, and the
widget renders the result.

| Tool               | Renders                                                                                                     | Use it for                          |
| ------------------ | ----------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| `showChart`        | An interactive chart: `bar`, `line`, `area`, `scatter`, `composed`, `radar`, `radialBar`, `pie` or `funnel` | Trends, comparisons, proportions    |
| `showTable`        | A sortable, formatted table                                                                                 | Lists of records with typed columns |
| `showStats`        | KPI cards with optional change indicators and sparklines                                                    | Headline numbers                    |
| `showImage`        | A single image with metadata and attribution                                                                | One picture                         |
| `showImageGallery` | A masonry gallery with a fullscreen lightbox                                                                | Several pictures                    |
| `showLinkPreview`  | A link card with title, description, image and favicon                                                      | Pointing at a page                  |
| `showCodeBlock`    | Syntax-highlighted code with optional filename and line highlights                                          | Snippets, config                    |
| `showCodeDiff`     | A unified or split diff                                                                                     | Proposed changes                    |
| `showMessageDraft` | An email or Slack draft for review                                                                          | Something the user will send        |

Table columns carry a format — `text`, `number`, `currency`, `percent`,
`date`, `delta`, `status`, `boolean`, `link`, `badge` or `array` — plus a
locale, so amounts and dates render correctly without the model formatting
them as strings. Percent formats declare whether the source value is a
fraction (`0.12`) or a unit (`12`), because guessing is wrong by a factor of
a hundred half the time.

The same provider also ships `quickchart-tool`, which returns a chart as an
image URL for surfaces that cannot render a live component.

## They are tools

Components live under the platform provider `rich-ui-components` and are
assigned per agent like any other tool:

```json theme={null}
{
  "agentTools": [
    { "tool_id": "showChart", "provider_id": "rich-ui-components" },
    { "tool_id": "showTable", "provider_id": "rich-ui-components" }
  ]
}
```

An agent carries only what it needs. A billing agent probably wants tables and
stats; a support agent that never shows data needs none. Fewer tools means
better tool selection, and the components count.

## Component anchors

An agent does not emit a component where the tool call happens to fall. It
**gathers data, registers each component, then writes one continuous answer**
with a marker placing each visual exactly where it belongs:

```text theme={null}
Bookings recovered strongly in Q3.

<component id="q3-bookings"/>

The dip in July is the renovation closure, not demand.
```

The sequence the agent follows:

<Steps>
  <Step title="Call the rendering tool with the complete payload">
    `showChart` with `id: "q3-bookings"` and every data point. The tool call
    is the registration — there is no other way to create a component.
  </Step>

  <Step title="Wait for the result">
    A successful result means the component now exists. An error result means
    the payload was rejected, with the reason named, and the agent fixes it and
    calls again.
  </Step>

  <Step title="Write the answer, placing each tag where it belongs">
    `<component id="q3-bookings"/>` on its own line — double quotes,
    self-closing, each id at most once. The tag is replaced by the rendered
    component.
  </Step>
</Steps>

Anchors replaced the older behaviour where a component appeared wherever the
tool call fell in the stream, which made the narrative arrive in fragments
around the visuals. With anchors the answer reads as one piece of prose with
the components inline.

### The failure to know about

The tag is a **pointer** to a component created by a tool call in the same
response. A tag whose id has no successful tool call behind it — the model did
the placement half and skipped the registration — renders as a visible
"Failed to show component" error. The agent is instructed never to write a tag
before its call has succeeded, and if it slips, to make the call before the
response ends. When you see that error in the wild, the fix is almost always a
model that is too small for the number of tools it holds, or a prompt that
asks it to "describe the chart" in a way that invites prose instead of a call.

Two more rules the agent follows:

* **Only the first payload for an id renders.** Calling the tool again with
  the same id in one response is refused with an error saying so; corrected
  content needs a new id.
* **Ids do not carry across turns.** To show a component again later, the
  agent calls the tool again in that response and anchors the new call.

## Making agents actually use them

An agent that holds components is told which rendering tools it has and when
to reach for them: tabular data, trends, KPIs, code, diffs, images and links
go through the matching tool rather than markdown. It is also told that a
component only exists through a real tool call — never a payload pasted as
JSON, never `<element>` or `{{id}}` placeholders, never "see the chart below".
You do not need to repeat any of this.

What *is* worth writing in your own prompt is domain guidance: "occupancy
questions get a line chart by month; rate comparisons get a table with one
row per room type." Tell the agent which shape suits which question, and let
the platform handle the mechanics.

The last two model steps of a turn are reserved: on the second-to-last step
only rendering tools remain callable, and on the last step none are, so an
agent that has been fetching data is pushed to render and answer rather than
run out of steps mid-table.

## Sizing

Tables default to their natural height (`maxHeight` is empty); set a CSS
height on the payload when a long table should scroll instead of growing.
Columns can be marked `hideOnMobile` or `truncate`, and given a `priority`,
so a wide table degrades gracefully on a phone. Component payloads are kept
in the thread history at a much higher cap than ordinary tool results, so a
large table still renders when the conversation is reopened.

## In workflows

A workflow can render components too: add a rich-UI step fed from earlier
steps, then place `<component id="<stepId>"/>` in the workflow's
`output_text`. The result thread renders it exactly as chat would. See
[User workflows](/docs/user-workflows#result-threads).
