Agent-Driven Interactive Cards
Agent-Driven Interactive Cards
Agent-Driven Interactive Cards
ASI:One lets agents drive interactive UI cards (drawer-based pickers, forms, review screens) through a metadata-driven wire protocol on the Agent Chat Protocol (ACP). This resource documents the agent-facing surface.
Inside the agent’s ChatMessage:
TextContent blocks carry plain narration shown in the chat bubble.MetadataContent block carries the card declaration.Required metadata keys:
Optional keys:
card_payload ≤ 64 KB.card_kind values are rejected.When validation fails, ASI one treats the message as a plain agent text reply.
carousel, detail, form, review) — use these whenever your card fits the pattern. They get polished, designed UI. See here.card_kind: "custom") — for shapes that don’t fit predefined schemas. You compose primitives directly. See here.When the user makes a selection, ASI:One forwards it back to your agent as a TextContent message in a follow-up ChatMessage. The shape of that text depends on how the user is interacting with the agent, so your agent must be prepared to handle both formats.
Used when the user is interacting through a complex task routed via ASI:One’s planner LLM. The planner reads the selection from its internal state and forwards it to your agent as a natural-language TextContent message.
The agent receives prose like:
“The user picked offer off_123 with cabin economy.”
The exact wording is generated by the planner LLM, but it will always include every identifier you put under the CTA’s selection payload (offer_id, action, form-field values, etc.) plus context from the prior task description.
Used when the user is interacting directly with the agent via an @mention (no planner in the loop). The selection is passed through as-is: a JSON object serialized to a string inside a TextContent message, built directly from the CTA details.
The JSON contains every value declared in the CTA’s selection payload — both the static selection text fields and any dynamically captured user inputs (form-field values, picked option ids, etc.).
Example:
Your agent should attempt to parse the TextContent as JSON first, and fall back to free-form text parsing if that fails.
ASI:One offers a playground where you can test different kinds of payload structures and preview how the generated card will look in ASI:One. You can also inspect the response JSON that will be generated when a CTA button is clicked.
This is a great place to first try out different payload shapes, finalise an approach, and then hook the metadata up in your agent. The card will be displayed and behave the same way as showcased in the playground.
Playground link: https://asi1.ai/developer/card-playground
card_protocol_version: "1" — the request is silently rejected.card_payload in extra layers (e.g. {"data": {...}}) — the schema expects the payload at the top level.is_terminal: "true" on a card that needs user input — the drawer never opens; the user can’t act.MetadataContent.metadata — the wire type is dict[str, str], so JSON-stringify nested structures.