Skip to main content
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. 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:
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:
The sequence the agent follows:
1

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.
2

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.
3

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.
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.