> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# A2UI Protocol

> Agent-to-User Interface protocol for agent-generated UIs

# A2UI (Agent-to-User Interface)

PraisonAI supports the [A2UI Protocol](https://github.com/google/A2UI) for generating rich, interactive user interfaces from AI agents using declarative JSON.

## Overview

A2UI is Google's open standard that allows agents to "speak UI" by sending declarative JSON describing UI components, which clients then render natively.

**Key Features:**

* **Declarative JSON** - Agents send UI descriptions, not executable code
* **Security First** - Only pre-approved components from a catalog can be rendered
* **LLM-Friendly** - Flat list of components with IDs, easy for LLMs to generate
* **Framework-Agnostic** - Same JSON works on Web, Flutter, React, etc.
* **Incrementally Updateable** - Agents can update UI progressively

## Quick Start

### Using A2UIAgent Wrapper

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonaiagents.ui.a2ui import A2UIAgent

# Create an agent
agent = Agent(
    name="Assistant",
    role="Helper",
    goal="Help users with tasks"
)

# Wrap with A2UI
a2ui_agent = A2UIAgent(agent=agent)

# Render a text response
messages = a2ui_agent.render_text("Hello World!", title="Greeting")

# Render a list of items
messages = a2ui_agent.render_list(
    title="Results",
    items=[
        {"title": "Item 1", "description": "First item"},
        {"title": "Item 2", "description": "Second item"},
    ]
)

# Render a form
messages = a2ui_agent.render_form(
    title="Contact Form",
    fields=[
        {"id": "name", "label": "Name", "type": "text"},
        {"id": "email", "label": "Email", "type": "email"},
    ],
    submit_action="submit_form"
)

# Get JSON output
json_output = a2ui_agent.to_json()
```

### Using Surface Builder

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.ui.a2ui import Surface, PathBinding

# Create a surface
surface = Surface(surface_id="main")

# Add components using fluent API
surface.text(id="title", text="Welcome", usage_hint="h1")
surface.text(id="subtitle", text=PathBinding(path="/subtitle"), usage_hint="h2")
surface.button(
    id="action-btn",
    child="btn-text",
    action_name="do_action",
    action_context=[{"key": "id", "value": "123"}],
    primary=True
)
surface.text(id="btn-text", text="Click Me")
surface.column(id="root", children=["title", "subtitle", "action-btn"])

# Set data model
surface.set_data("subtitle", "Hello World")

# Generate A2UI messages
messages = surface.to_messages()
json_output = surface.to_json()
```

### Using Templates

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.ui.a2ui import (
    ChatTemplate,
    ListTemplate,
    FormTemplate,
    DashboardTemplate,
)

# Chat Template
chat = ChatTemplate(surface_id="chat")
chat.add_user_message("Hello!")
chat.add_agent_message("Hi there! How can I help?")
messages = chat.to_messages()

# List Template
list_ui = ListTemplate(surface_id="results", title="Search Results")
list_ui.add_item(title="Result 1", description="First result", image_url="https://...")
list_ui.add_item(title="Result 2", description="Second result")
messages = list_ui.to_messages()

# Form Template
form = FormTemplate(surface_id="contact", title="Contact Us")
form.add_text_field(id="name", label="Your Name")
form.add_email_field(id="email", label="Email Address")
form.add_number_field(id="phone", label="Phone Number")
form.set_submit_action("submit_contact", "Send Message")
messages = form.to_messages()

# Dashboard Template
dashboard = DashboardTemplate(surface_id="dashboard", title="Analytics")
dashboard.add_panel(id="stats", title="Statistics", content="1,234 users")
dashboard.add_panel(id="chart", title="Chart", content="[Chart visualization]")
messages = dashboard.to_messages()
```

## Components

### Display Components

| Component        | Description                                           |
| ---------------- | ----------------------------------------------------- |
| `TextComponent`  | Text display with usage hints (h1, h2, body, caption) |
| `ImageComponent` | Image display with fit and usage hints                |
| `IconComponent`  | Icon display                                          |

### Layout Components

| Component         | Description                |
| ----------------- | -------------------------- |
| `RowComponent`    | Horizontal layout          |
| `ColumnComponent` | Vertical layout            |
| `CardComponent`   | Card container             |
| `ListComponent`   | List with template support |

### Input Components

| Component                | Description        |
| ------------------------ | ------------------ |
| `ButtonComponent`        | Button with action |
| `TextFieldComponent`     | Text input field   |
| `CheckBoxComponent`      | Checkbox input     |
| `SliderComponent`        | Slider input       |
| `DateTimeInputComponent` | Date/time picker   |

## Data Binding

Use `PathBinding` to reference values in the data model:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.ui.a2ui import Surface, PathBinding

surface = Surface(surface_id="main")

# Static text
surface.text(id="static", text="Hello")

# Dynamic text from data model
surface.text(id="dynamic", text=PathBinding(path="/user/name"))

# Set the data
surface.set_data("user", {"name": "John Doe"})
```

## Actions

Define button actions with context:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.ui.a2ui import Surface

surface = Surface(surface_id="main")

surface.text(id="btn-label", text="Book Now")
surface.button(
    id="book-btn",
    child="btn-label",
    action_name="book_restaurant",
    action_context=[
        {"key": "restaurant_id", "value": "123"},
        {"key": "name", "value": {"path": "/restaurant/name"}},  # Dynamic value
    ],
    primary=True
)
```

## A2A Integration

A2UI works alongside the A2A (Agent-to-Agent) protocol:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.ui.a2ui import (
    Surface,
    create_a2ui_part,
    is_a2ui_part,
    get_a2ui_agent_extension,
    A2UI_MIME_TYPE,
)

# Create surface
surface = Surface(surface_id="main")
surface.text(id="msg", text="Hello from A2A")
surface.column(id="root", children=["msg"])

# Wrap as A2A DataPart
part = create_a2ui_part({"messages": surface.to_messages()})

# Check if part is A2UI
assert is_a2ui_part(part)
assert part.metadata["mimeType"] == A2UI_MIME_TYPE

# Get A2A AgentExtension for Agent Card
extension = get_a2ui_agent_extension()
```

## Message Types

A2UI uses four message types:

| Message                   | Description               |
| ------------------------- | ------------------------- |
| `CreateSurfaceMessage`    | Create a new UI surface   |
| `UpdateComponentsMessage` | Update surface components |
| `UpdateDataModelMessage`  | Update the data model     |
| `DeleteSurfaceMessage`    | Delete a surface          |

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.ui.a2ui import (
    CreateSurfaceMessage,
    UpdateComponentsMessage,
    UpdateDataModelMessage,
    DeleteSurfaceMessage,
    TextComponent,
)

# Create surface
create_msg = CreateSurfaceMessage(
    surface_id="main",
    catalog_id="https://a2ui.dev/standard"
)

# Update components
text = TextComponent(id="title", text="Hello", usage_hint="h1")
update_msg = UpdateComponentsMessage(
    surface_id="main",
    components=[text]
)

# Update data model
data_msg = UpdateDataModelMessage(
    surface_id="main",
    value={"title": "Hello World"}
)

# Delete surface
delete_msg = DeleteSurfaceMessage(surface_id="main")
```

## API Reference

### A2UIAgent

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
A2UIAgent(
    agent: Agent,                    # PraisonAI Agent instance
    surface_id: str = None,          # Surface ID (auto-generated if not provided)
    catalog_id: str = STANDARD_CATALOG_ID,  # Component catalog
)
```

**Methods:**

* `render_text(text, title=None)` - Render text response
* `render_list(title, items, ...)` - Render list of items
* `render_form(title, fields, ...)` - Render form
* `chat(message)` - Send message to agent
* `to_messages()` - Get A2UI messages
* `to_json()` - Get JSON string
* `to_a2a_part()` - Get A2A DataPart

### Surface

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
Surface(
    surface_id: str,                 # Unique surface ID
    catalog_id: str = STANDARD_CATALOG_ID,  # Component catalog
)
```

**Methods:**

* `add(component)` - Add a component
* `set_data(key, value)` - Set data model value
* `text(id, text, ...)` - Add text component
* `image(id, url, ...)` - Add image component
* `button(id, child, ...)` - Add button component
* `card(id, child, ...)` - Add card component
* `row(id, children, ...)` - Add row layout
* `column(id, children, ...)` - Add column layout
* `list(id, children, ...)` - Add list component
* `text_field(id, label, ...)` - Add text field
* `to_messages()` - Generate A2UI messages
* `to_json()` - Generate JSON string

## Related

* [A2A Protocol](/features/a2a) - Agent-to-Agent communication
* [AG-UI Protocol](/ui/overview) - CopilotKit integration
* [Workflows](/features/workflows) - Multi-agent workflows
