Skip to content

A2UI Plugin

A2UI lets an agent drive Player UI directly: instead of authoring a Flow by hand, an agent emits a flat, id-linked snapshot of components (the A2UI v0.9.1 reference catalog — Row, Column, List, Text, Image, Icon, Divider, Button, TextField, CheckBox, Slider, DateTimeInput, ChoicePicker, Card, Modal, Tabs) and Player adapts it into a normal Flow.

The A2UI plugin registers a content adapter that recognizes this snapshot shape and transforms it, so everything downstream (i.e schema, validation, data binding, navigation, and rendering) runs through Player’s existing pipeline unchanged. There’s nothing agent-specific to learn on the rendering side; you’re still just registering asset renderers like any other Player content.

Given a snapshot like:

{
"surfaceId": "greeting",
"data": { "message": "Hello from A2UI" },
"components": [
{ "id": "root", "component": "Column", "children": ["header", "body"] },
{ "id": "header", "component": "Text", "text": "Welcome" },
{ "id": "body", "component": "Card", "child": "content" },
{ "id": "content", "component": "Text", "text": { "path": "/message" } }
]
}

the adapter inlines the id-linked children into nested { asset: ... } wrappers, resolves { path: ... } references into data bindings, synthesizes a schema (including any per-input checks), and emits a single VIEW state plus one END state per unique event/action outcome — producing a Flow that Player resolves and renders exactly as it would DSL- or JSON-authored content.

When passing A2UI content to Player’s start function,the version of that content should additionally be supplied to ensure the correct plugin is used to transform that content. Currently, A2UI version support is outlined below.

A2UIVersionStatus
0.9Supported
1.0+Not yet supported

Install the plugin:

Terminal window
npm i @player-ui/a2ui-plugin

Register it, then start a flow with format: "a2ui" instead of a normal Flow document:

import { Player } from "@player-ui/player";
import { A2UIPlugin } from "@player-ui/a2ui-plugin";
const player = new Player({ plugins: [new A2UIPlugin()] });
player.start(a2uiSnapshot, { format: "a2ui", version: "0.9" });

A2UIPlugin bundles the content adapter, asset transforms, standard expression functions (required, regex, length, numeric, email, formatString, formatNumber, formatCurrency, formatDate, pluralize, openUrl, and, or, not), and their Player validation-type counterparts which is everything needed to resolve the adapted Flow.

Wiring up the base Player plus the A2UI plugin (and, on native platforms, the renderer catalog) is the same handful of lines on every platform. To make it as easy as possible to get started with Player and A2UI, we offer preconfigured player packages on each platform with all the necessary plugins for A2UI rendering included.

Install:

Terminal window
npm i @player-ui/a2ui
import { A2UIReactPlayer } from "@player-ui/a2ui";
const player = new A2UIReactPlayer();
await player.start(a2uiSnapshot, { format: "a2ui", version: "0.9" });
implementation("com.intuit.playerui:a2ui:$PLAYER_VERSION")
import com.intuit.playerui.a2ui.A2UIHeadlessPlayer
val player = A2UIHeadlessPlayer()
player.start(snapshot, mapOf("format" to "a2ui", "version" to "0.9")).await()

Input components can carry a checks array describing per-binding validation:

{
"id": "email_field",
"component": "TextField",
"text": { "path": "/user/email" },
"checks": [
{ "call": "required", "message": "Email is required" },
{ "call": "email", "message": "Must be a valid email" }
]
}

Supported call names are required, regex (args.pattern), length (args.min/args.max), numeric (args.min/args.max), and email. The adapter hoists these into a synthesized Player schema with validation references, so they run through Player’s normal ValidationController with a change trigger. The optional message on a check overrides the validator’s default message.