Skip to main content
Agents describe tabular or chart data once with a TABLE or CHART block, and every channel renders it natively where supported or degrades deterministically to a markdown table or text summary everywhere else.

Quick Start

1

Agent returns a table

An agent returns a MessagePresentation with a TABLE block from a tool — pass numbers or ints freely, cells are stringified for you:
2

Add a chart

A CHART block carries a chart_kind and one or more series; each series is a label plus a list of numeric points:

How It Works

A TABLE block clamps to the channel’s row and column caps, then either stays a native table or degrades to a markdown table inside a TEXT block. A CHART block stays native where charts are supported, or degrades to a one-line-per-series text summary. Every channel defaults to off — Slack, Telegram, Discord, and WhatsApp preset supports_tables=False / supports_charts=False, so behaviour today is a deterministic markdown/text degrade until a channel opts in.

Configuration Options

BlockType — new members

PresentationBlock — new fields

Factories

make_table coerces every column and cell to str, so agents pass numbers or ints freely. Chart series items are dicts with label (str) and points (list of numbers); any extra keys round-trip through to_dict() / from_dict().

PresentationLimits — new capability flags

Helpers

table_to_markdown produces GitHub-flavoured markdown with | cells escaped and short rows padded to header width. chart_to_text renders "<Caption or Kind chart>\n<label>: p1, p2, p3\n..." — deterministic, one line per series.

Common Patterns

Agent returns a table from a tool — describe the data once and let the channel pick the best rendering:
Chart with caption — the caption becomes the title on native renders and the first line of the text summary elsewhere:
Opt a custom channel into native tables — return an updated PresentationLimits from your channel’s capability method:

Best Practices

Native widgets typically cap rows well below 50 — set max_table_rows on your channel to reflect the true limit so adapt_presentation clamps before rendering.
Do not pre-format a markdown table in a TEXT block. Send TABLE / CHART blocks and let each channel pick the best rendering.
Any chart is always readable as text via chart_to_text, so you never lose data on plain-text channels.
Numbers and booleans are coerced to str. For a specific format (currency, %), format the value in your tool before passing it in.

Message Presentation

Attach buttons, menus, and blocks to agent replies

Channel Capabilities

What each channel can render natively