> ## 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.

# Rendering Surfaces

> Eight display channels in Profy: ToolCallCard, Inline Visualization, A2UI, FilePanel, Preview, Browser, Widget, Video Timeline Widget

# Eight Rendering Surfaces

Profy has eight channels for displaying Agent-produced content to users. Understanding their differences helps Plugin creators choose the right output method.

## Overview

| Surface                   | Location                  | Rendering                   | Source                 | Interactivity                    | Typical Use                            |
| ------------------------- | ------------------------- | --------------------------- | ---------------------- | -------------------------------- | -------------------------------------- |
| **ToolCallCard**          | Chat inline               | Pure React DOM              | Agent SSE tool\_calls  | Read-only                        | Tool status + results                  |
| **Inline Visualization**  | Chat inline               | `<iframe srcdoc>` sandbox   | `result.inline_vis`    | Interactive (sandboxed JS)       | D3 charts, Three.js scenes             |
| **A2UI**                  | Chat inline               | Native React components     | `result.a2ui`          | Bidirectional (button callbacks) | Structured interactive UI              |
| **FilePanel**             | Right panel "Files" Tab   | img/video/iframe srcDoc     | Sandbox files / COS    | Read-only preview                | Browse agent outputs                   |
| **Preview**               | Right panel "Preview" Tab | `<iframe src={url}>`        | Sandbox dev server     | Full interaction (HMR)           | Live Sites preview                     |
| **Browser**               | Right panel "Browser" Tab | `<iframe src={noVNC}>`      | noVNC → Sandbox Chrome | VNC remote control               | Browser automation                     |
| **Widget**                | Right panel "Widget" Tab  | `<iframe srcDoc={html}>`    | MCP tool result.widget | Bidirectional JSON-RPC           | Interactive tool results               |
| **Video Timeline Widget** | Right panel "Widget" Tab  | Widget instance (Twick SDK) | `timeline_edit` tool   | Bidirectional JSON-RPC           | Professional multi-track video editing |

## 1. ToolCallCard

**Location**: Inline in chat message stream

**Key traits**:

* Pure React DOM (no iframe)
* Code highlighting with Prism.js
* Expand/collapse support
* Can contain images (base64 or URL)

**Trigger**: Automatically rendered from SSE `tool_calls` events

**Capabilities**:

* Text results (Markdown rendered)
* Code blocks (syntax highlighted)
* Images (screenshots etc.)
* Structured cards (via plugin manifest `ui.toolCallCards` templates)
* Status indicators (in-progress/success/failure)

**Best for**: Tool execution status, search results, short answers, screenshots

## 2. Inline Visualization

**Location**: Inline in chat message stream (following ToolCallCard)

**Key traits**:

* Renders full HTML/CSS/JS via `<iframe srcdoc>`
* Sandboxed: `sandbox="allow-scripts"` (no network, no navigation, no form submit)
* Auto-height based on content (via `postMessage` reporting `document.body.scrollHeight`)
* Expand/collapse (default max 400px, expanded 800px)
* Dark/light theme auto-adaptation

**Trigger**: Tool returns `result.inline_vis` field (containing `title`, `html`, optional `css`)

**Communication protocol**:

```javascript theme={null}
// Content → Host (report height)
window.parent.postMessage({
  type: "profy-inline-vis-height",
  toolCallId: "...",
  height: document.body.scrollHeight
}, "*")
```

**Best for**:

* D3/Vega-Lite data charts
* Three.js 3D scene previews
* Statistical visualizations
* Any lightweight visualization needing JavaScript interactivity

**Difference from Widget**:

* Inline Visualization lives in the chat stream (doesn't occupy right panel)
* No bidirectional JSON-RPC (only one-way height reporting)
* For "glance and understand" visualizations, not sustained interaction tools

## 3. A2UI (Agent to UI)

**Location**: Inline in chat message stream

**Key traits**:

* **Native React component** rendering (no iframe, better performance than srcdoc)
* Declarative JSON → local UI component mapping
* Supports user interaction: button clicks trigger Actions sent back to Agent
* 16 built-in components covering common UI patterns
* Theme and dark mode auto-adaptation

**Trigger**: Agent calls `render_ui` tool → returns `result.a2ui` field

**Component categories**:

| Category       | Components                                                                                   |
| -------------- | -------------------------------------------------------------------------------------------- |
| Layout         | `Row`, `Column`, `Card`                                                                      |
| Content        | `Text`, `Image`, `Divider`, `Badge`, `List`, `Table`                                         |
| Interactive    | `Button`                                                                                     |
| Profy Business | `ExpertCard`, `CreditDisplay`, `PlanBadge`, `StatusIndicator`, `PricingTable`, `ProgressBar` |

**Interaction loop**:

```
Agent calls render_ui(components=[...])
  → Frontend renders native React components
  → User clicks Button(action="upgrade_plan")
  → Action event dispatched to Agent
  → Agent handles follow-up logic
```

**Best for**:

* Structured information display (plan comparisons, status dashboards)
* Interactive confirmation/selection cards
* Business data display (credit balance, subscription status)
* Action prompts (buttons triggering next steps)

**Difference from Inline Visualization**:

* A2UI is declarative JSON, no HTML/CSS/JS authoring needed
* Renders as native React components (better consistency, better performance)
* Supports Action callbacks (true bidirectional interaction)
* Cannot do freeform drawing/Canvas/WebGL (limited to predefined component set)

See [A2UI Component Documentation](/en/documentation/plugins/a2ui) for details.

## 4. FilePanel

**Location**: Right panel "Files" tab

**Key traits**:

* Renders based on file type
* HTML/SVG uses `<iframe srcDoc>` (sandboxed)
* Code files get syntax highlighting

**Rendering by file type**:

| Type                     | Method            |
| ------------------------ | ----------------- |
| Image (png/jpg/gif/webp) | `<img>`           |
| Video (mp4/webm)         | `<video>`         |
| Audio (mp3/wav)          | `<audio>`         |
| PDF                      | PDF.js            |
| Markdown                 | react-markdown    |
| Code                     | Prism.js          |
| HTML/SVG                 | `<iframe srcDoc>` |

**Best for**: Viewing files generated by the agent

## 5. Preview

**Location**: Right panel "Preview" tab

**Key traits**:

* Connects to sandbox dev server via `<iframe src={proxyUrl}>`
* Default port 5173 (TanStack Start / Vite)
* HMR support — code changes reflect instantly
* Fully interactive

**Trigger**: Sites plugin's `open_preview` tool call

**Best for**: Live development preview of Sites projects

## 6. Browser

**Location**: Right panel "Browser" tab

**Key traits**:

* noVNC WebSocket connection to sandbox Chrome desktop
* Shows full browser GUI (address bar, tabs)
* User can directly interact via VNC

**Trigger**: `browser(action="navigate")` opens the panel

**Best for**: Visualizing browser automation, user intervention (CAPTCHAs)

## 7. Widget

**Location**: Right panel "Widget" tab

**Key traits**:

* `<iframe srcDoc={html}>` injection
* Sandboxed: `sandbox="allow-scripts allow-forms"`
* Bidirectional JSON-RPC communication
* Can call host-provided MCP tools

**Trigger**: MCP tool returns `result.widget` field

**Communication protocol**:

```javascript theme={null}
// Widget → Host (call tool)
window.parent.postMessage({
  jsonrpc: "2.0",
  method: "tools/call",
  params: { name: "tool_name", arguments: {...} },
  id: 1
}, "*")

// Host → Widget (return result)
window.addEventListener("message", (e) => {
  if (e.data.jsonrpc === "2.0" && e.data.id === 1) {
    console.log(e.data.result)
  }
})
```

**Best for**: Interactive games/demos, dashboards, forms, rich UI with bidirectional communication

## 8. Video Timeline Widget

**Location**: Right panel "Widget" tab (specialized Widget instance)

**Key traits**:

* Professional multi-track timeline editor powered by Twick SDK
* Bidirectional communication with Agent via JSON-RPC bridge
* Agent can programmatically manipulate the timeline via `timeline_edit` tool
* Users can manually drag, trim, and arrange clips

**Trigger**: `movie(action="assemble")` or `timeline_edit` tool calls open the widget

**Agent operations**:

```python theme={null}
timeline_edit(action="add_clip", track=0, asset_id="clip_001", start=0, duration=5.0)
timeline_edit(action="split", track=0, clip_id="c1", at=2.5)
timeline_edit(action="add_transition", from_clip="c1", to_clip="c2", type="crossfade", duration=0.5)
```

**Best for**: Professional video editing, multi-track timeline arrangement, clip assembly with transitions

See [Video Production Documentation](/en/documentation/plugins/video-production) for details.

## Selection Guide

```mermaid theme={null}
graph TD
    A[Agent produces content] --> B{Interactive?}
    B -->|No| C{Is it a file?}
    B -->|Yes| D{Interaction type?}
    C -->|Yes| E[FilePanel]
    C -->|No| F{Is it a visualization?}
    F -->|Yes| L[Inline Visualization]
    F -->|No| M[ToolCallCard]
    D -->|Structured UI buttons/forms| N[A2UI]
    D -->|Free HTML + bidirectional comm| G[Widget]
    D -->|Video timeline editing| O[Video Timeline Widget]
    D -->|Dev server preview| I[Preview]
    D -->|Full browser GUI| K[Browser]
```

## Plugin Creator Guide

When creating a Plugin, choose your output channel:

1. **Short results** (\< 500 chars) → Return text, renders as ToolCallCard
2. **Screenshots/images** → Return base64 image, renders in ToolCallCard
3. **Lightweight visualization** (charts/3D previews) → Return via `result.inline_vis`, renders as Inline Visualization
4. **Structured interactive UI** (buttons/tables/cards) → Use `render_ui` tool + `result.a2ui`, renders as A2UI
5. **Generated files** → Write to sandbox filesystem, FilePanel shows automatically
6. **Interactive tool UI** (needs free HTML + bidirectional comm) → Return via `result.widget`, renders as Widget
7. **Live dev preview** → Start dev server + `open_preview`, renders as Preview
8. **Browser automation viz** → Trigger via browser tool, renders as Browser
