Blocks
Structured, typed visual outputs for agent work — DataSpec, MCP Apps, artifacts, and 13 show primitives.
Blocks are typed outputs that make agent work inspectable. Every canvas block is created through one of four paths — the agent picks the right one based on what it's emitting.
The four block paths
| Path | Block type | When |
|---|---|---|
data_block tool | type: "data" | Default for any structured data display. The agent emits a typed DataSpec; the renderer builds 100% shadcn UI from it. |
show tool | one of 13 system primitives | Interactive primitives with their own state and behaviour — see below. |
| MCP App reference | type: "mcp-app" | Real connector outputs (Gmail, Slack, GitHub, Notion, Linear, Stripe, etc.). Created by connector flows. Renders a hand-coded ui.tsx in a sandboxed iframe. |
artifact_create | type: "artifact" | Multi-file mini-app the user explicitly asked for. Multi-file project + sqlite. |
The AI never writes UI code outside of artifacts. DataSpec is typed JSON the agent fills; MCP App ui.tsx is hand-coded by humans; artifacts are explicit user request only.
DataSpec sub-types (the data_block catalog)
A data block's data field is a DataSpec. Pick the right type:
type | Use for |
|---|---|
markdown | Long-form prose, notes, summaries |
callout | Highlighted info/warning/success/danger bands |
metric | One headline number with delta + label |
kpi-grid | A small grid of metrics |
card | A single rich card with title, body, image, actions |
table | Rows × columns — sortable, filterable, sticky header, drag-reorder columns, resizable columns |
list | Vertical list of titled items with optional images, statuses, actions |
form | An input form with typed fields and submission |
chart | Line, bar, area, pie, or scatter |
timeline | Dated events down a left rail |
kanban | Columns of cards (drag between columns) |
dashboard | A composition of metrics, charts, and lists |
gallery | Images, videos, audio — single or multi |
app-view | App-shaped previews via named presets (tweets, emails, products, calendar events, contacts, files, etc.) |
map | A pannable map with markers |
steps | A numbered sequence |
comparison | Side-by-side comparison of options |
calendar | Calendar grid with events |
pdf | A rendered PDF preview |
Each sub-type has a strict Zod schema. The agent fills the fields; the renderer is hand-built with shadcn primitives.
Variant whitelists
The agent picks from these — never invents values:
- Buttons / badges:
default | secondary | destructive | outline | ghost | muted - Status:
default | success | warning | destructive | info | muted - Trend:
up | down | neutral - Chart kind:
line | bar | area | pie | scatter
Colors
When a DataSpec field accepts a hex (e.g. a chart series colour, callout marker, badge accent), the AI picks from a curated 12-colour 2026 palette: slate, azure, iris, emerald, sage, amber, honey, rose, violet, teal, fuchsia, plus cloud (Pantone 2026). No neon, no fully-saturated CSS named colours, no invented hexes.
The 13 show primitives
Use the show tool only for interactive primitives that have their own state and behaviour. Plain data displays belong in data_block.
document, review, code, spreadsheet, google-workspace, draw, browser, sandbox, terminal, timer, stopwatch, swarm, chat.
draw (Excalidraw), browser (live Browserbase session), and google-workspace (linked Google Docs/Sheets/Slides) are "native interactive" blocks — their content is always interactive, never a drag target.
App-view presets
app-view is the DataSpec sub-type for generated drafts and previews that should look like a recognizable app surface. Examples:
- Social:
social-post,social-thread,social-poll,social-profile— Twitter / X / LinkedIn / Bluesky / Threads. Threads render with a continuous left connector line linking avatars. - Messaging:
message-thread,message-direct— Slack-style with avatars (themed viabg+colorhex on the avatar spec), timestamps, hover rows. - Email:
email-draft,email-inbox— Gmail-style. - Work items:
issue-task,pull-request— GitHub / Linear style. - Commerce:
product-card,cart,checkout,order— Shopify style with line items, totals, statuses. - Calendar:
calendar-event,calendar-agenda. - Media:
audio-track,audio-playlist,video-clip,video-playlist— ElevenLabs-style pill audio player; playlists auto-fit to their content height. - Files:
file-preview,pdf-preview. - Generic web:
bookmark,link-preview,news-article,quote. - Domain-specific: weather, sports, finance, food, healthcare, real-estate, gaming, science, info.
Real connector outputs still become mcp-app blocks via connector flows. app-view is for the agent's own drafts and previews.
Social posts must include media
When drafting a tweet, X / LinkedIn / Bluesky / Threads post, or any app-view with surface: "social", the agent fetches or generates a relevant image, saves it via image_save, and attaches it on media.fileId. A tweet without media looks unfinished. The only exception is when the user explicitly says "text only".
Images on the canvas
Never put external https:// URLs directly in DataSpec image fields — browsers will block them with CORS errors. The agent always calls image_save first, gets a file id, and references it via fileId (preferred) or src: "file:<id>". The renderer resolves file ids to a canvas-safe URL automatically.
Why blocks matter
- They keep long-running work visible
- They make artifacts easier to review than raw JSON
- They give agents a stable object to update (via
update_blockpatches) instead of rewriting whole conversations
Use blocks whenever the output has structure, needs revision, or should remain visible after the chat moves on.
How agents discover and edit blocks
search_blocks— list/search canvas blocks by query and typesearch_block— find exact JSON Pointer paths inside one block's data (for patch operations)read_block/narrate_block— read full data; narrate for voice modesupdate_block— acceptstitle,patch(array of JSON Pointer ops), or both. Preferpatchover replacing wholedatadelete_block— soft-deletecanvas_inspect— schema/render validation after creating or patchingcanvas_screenshot— visual verification when layout matters
Two workflow rules the agent follows:
- Search before creating. If a block of the same purpose exists,
update_blockit instead of creating a duplicate. - Patch, don't replace. Use
search_blockto find JSON Pointer paths (e.g./content,/rows/2/status), thenupdate_blockwithpatchfor surgical edits.