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

# A2UI (Agent to UI)

> Declarative JSON-driven native React UI rendering surface with 16 components and user interaction callbacks

# A2UI — Agent to UI

A2UI lets the Agent describe UI structure through declarative JSON. The frontend renders it as native React components inline in the chat area. When users interact with components (e.g., clicking buttons), events are dispatched back to the Agent for follow-up processing.

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant Agent
    participant Frontend
    participant User
    Agent->>Frontend: render_ui(components=[...])
    Frontend->>Frontend: Parse JSON → render React components
    Frontend->>User: Display structured UI
    User->>Frontend: Click Button(action="confirm")
    Frontend->>Agent: dispatch action event
    Agent->>Agent: Handle user choice
```

## Basic Usage

The Agent calls the `render_ui` tool with a components array:

```python theme={null}
render_ui(components=[
    {
        "type": "Card",
        "title": "Current Plan",
        "children": [
            {"type": "PlanBadge", "plan": "pro"},
            {"type": "Text", "content": "Valid until 2026-08-01"},
            {"type": "Button", "label": "Upgrade Plan", "action": "upgrade", "variant": "primary"}
        ]
    }
])
```

The tool result contains an `a2ui` field. When `StageGroup` detects this field, it renders the `A2UIRenderer` component.

## Component Catalog

### Layout Components

#### Row

Arranges children horizontally.

| Prop       | Type                           | Description                              |
| ---------- | ------------------------------ | ---------------------------------------- |
| `gap`      | `number`                       | Spacing between children (px), default 8 |
| `align`    | `"start" \| "center" \| "end"` | Vertical alignment                       |
| `children` | `Component[]`                  | Child components                         |

#### Column

Arranges children vertically.

| Prop       | Type          | Description                              |
| ---------- | ------------- | ---------------------------------------- |
| `gap`      | `number`      | Spacing between children (px), default 8 |
| `children` | `Component[]` | Child components                         |

#### Card

Container with title and border.

| Prop       | Type          | Description  |
| ---------- | ------------- | ------------ |
| `title`    | `string?`     | Card title   |
| `subtitle` | `string?`     | Subtitle     |
| `children` | `Component[]` | Card content |

### Content Components

#### Text

Text display with Markdown support.

| Prop      | Type                                                        | Description                       |
| --------- | ----------------------------------------------------------- | --------------------------------- |
| `content` | `string`                                                    | Text content (Markdown supported) |
| `size`    | `"sm" \| "md" \| "lg"`                                      | Font size, default `"md"`         |
| `weight`  | `"normal" \| "medium" \| "bold"`                            | Font weight                       |
| `color`   | `"default" \| "muted" \| "success" \| "warning" \| "error"` | Semantic color                    |

#### Image

Image display.

| Prop     | Type      | Description |
| -------- | --------- | ----------- |
| `src`    | `string`  | Image URL   |
| `alt`    | `string?` | Alt text    |
| `width`  | `number?` | Width (px)  |
| `height` | `number?` | Height (px) |

#### Divider

Horizontal separator.

| Prop    | Type      | Description                       |
| ------- | --------- | --------------------------------- |
| `label` | `string?` | Text in the middle of the divider |

#### Badge

Label/badge.

| Prop      | Type                                                       | Description   |
| --------- | ---------------------------------------------------------- | ------------- |
| `text`    | `string`                                                   | Badge text    |
| `variant` | `"default" \| "success" \| "warning" \| "error" \| "info"` | Style variant |

#### List

List display.

| Prop      | Type       | Description                      |
| --------- | ---------- | -------------------------------- |
| `items`   | `string[]` | List items                       |
| `ordered` | `boolean`  | Whether ordered, default `false` |

#### Table

Table display.

| Prop      | Type                             | Description                   |
| --------- | -------------------------------- | ----------------------------- |
| `columns` | `{key: string, label: string}[]` | Column definitions            |
| `rows`    | `Record<string, string>[]`       | Row data                      |
| `compact` | `boolean`                        | Compact mode, default `false` |

### Interactive Components

#### Button

Clickable button that triggers an Action callback.

| Prop       | Type                                                   | Description                          |
| ---------- | ------------------------------------------------------ | ------------------------------------ |
| `label`    | `string`                                               | Button text                          |
| `action`   | `string`                                               | Action identifier sent back on click |
| `variant`  | `"primary" \| "secondary" \| "destructive" \| "ghost"` | Button style                         |
| `disabled` | `boolean`                                              | Whether disabled                     |
| `payload`  | `Record<string, any>?`                                 | Additional data sent with the action |

### Profy Business Components

#### ExpertCard

Expert information card.

| Prop          | Type      | Description       |
| ------------- | --------- | ----------------- |
| `identifier`  | `string`  | Expert identifier |
| `name`        | `string`  | Expert name       |
| `avatar`      | `string?` | Avatar URL        |
| `description` | `string?` | Short description |

#### CreditDisplay

Credit balance display.

| Prop      | Type     | Description                  |
| --------- | -------- | ---------------------------- |
| `balance` | `number` | Current balance              |
| `unit`    | `string` | Unit text, default "credits" |

#### PlanBadge

Subscription plan badge.

| Prop   | Type                                                   | Description |
| ------ | ------------------------------------------------------ | ----------- |
| `plan` | `"free" \| "starter" \| "pro" \| "flagship" \| "team"` | Plan code   |

#### StatusIndicator

Status indicator.

| Prop     | Type                                             | Description |
| -------- | ------------------------------------------------ | ----------- |
| `status` | `"active" \| "inactive" \| "pending" \| "error"` | Status      |
| `label`  | `string`                                         | Status text |

#### PricingTable

Pricing comparison table.

| Prop     | Type                                        | Description       |
| -------- | ------------------------------------------- | ----------------- |
| `plans`  | `{name, price, features[], highlighted?}[]` | Plan list         |
| `action` | `string?`                                   | CTA button action |

#### ProgressBar

Progress bar.

| Prop    | Type                                             | Description           |
| ------- | ------------------------------------------------ | --------------------- |
| `value` | `number`                                         | Current value (0-100) |
| `label` | `string?`                                        | Progress label        |
| `color` | `"default" \| "success" \| "warning" \| "error"` | Color                 |

## Action Handling

When a user clicks a Button with an `action` prop, the frontend dispatches the event to the Agent:

```json theme={null}
{
  "type": "a2ui_action",
  "action": "upgrade",
  "payload": {"plan": "pro"},
  "componentPath": "card.0.button.2"
}
```

The Agent reads this action in its next reasoning turn and can respond accordingly (e.g., navigate to payment, update displayed content).

## Examples

### Plan Comparison

```python theme={null}
render_ui(components=[
    {"type": "Text", "content": "Choose your plan", "size": "lg", "weight": "bold"},
    {
        "type": "PricingTable",
        "plans": [
            {"name": "Free", "price": "0", "features": ["100 credits/day", "Basic models"]},
            {"name": "Pro", "price": "$49/mo", "features": ["5000 credits/mo", "All models", "Priority"], "highlighted": True},
            {"name": "Flagship", "price": "$199/mo", "features": ["20000 credits/mo", "All models", "Dedicated support"]}
        ],
        "action": "select_plan"
    }
])
```

### Status Dashboard

```python theme={null}
render_ui(components=[
    {
        "type": "Card",
        "title": "Account Overview",
        "children": [
            {
                "type": "Row",
                "gap": 16,
                "children": [
                    {"type": "CreditDisplay", "balance": 4520},
                    {"type": "PlanBadge", "plan": "pro"},
                    {"type": "StatusIndicator", "status": "active", "label": "Subscription active"}
                ]
            },
            {"type": "Divider"},
            {"type": "ProgressBar", "value": 68, "label": "Monthly usage 68%"},
            {
                "type": "Row",
                "gap": 8,
                "children": [
                    {"type": "Button", "label": "Top Up", "action": "recharge", "variant": "primary"},
                    {"type": "Button", "label": "View Details", "action": "view_detail", "variant": "ghost"}
                ]
            }
        ]
    }
])
```

### Action Confirmation

```python theme={null}
render_ui(components=[
    {
        "type": "Card",
        "title": "Confirm Action",
        "children": [
            {"type": "Text", "content": "About to delete expert 'Financial Advisor'. This cannot be undone.", "color": "warning"},
            {
                "type": "Row",
                "gap": 8,
                "align": "end",
                "children": [
                    {"type": "Button", "label": "Cancel", "action": "cancel", "variant": "ghost"},
                    {"type": "Button", "label": "Delete", "action": "confirm_delete", "variant": "destructive", "payload": {"identifier": "financial-advisor"}}
                ]
            }
        ]
    }
])
```

## Best Practices

1. **Prefer A2UI over Inline Visualization** when displaying structured data (tables, lists, status) — A2UI components are more consistent and performant
2. **Keep component trees shallow** — no more than 3 levels of nesting
3. **Use snake\_case for action names** — e.g., `confirm_delete`, `select_plan`, making them easy for the Agent to parse
4. **Use payload for context** — Button's `payload` field carries additional data the Agent needs, avoiding positional inference
5. **Group with Cards** — logically related components belong in the same Card for visual coherence
6. **Choose Inline Visualization when you need freeform drawing/Canvas/WebGL** — A2UI only supports predefined components
