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

# 渲染面（Display Surfaces）

> Profy 中八种将内容展示给用户的通道：ToolCallCard、Inline Visualization、A2UI、FilePanel、Preview、Browser、Widget、Video Timeline Widget

# 八种渲染面

Profy 有八种将 Agent 产出内容展示给用户的通道。理解它们的区别有助于 Plugin 创作者选择正确的输出方式。

## 总览对比

| 渲染面                       | 位置            | 渲染技术                     | 内容来源                  | 交互性         | 典型场景              |
| ------------------------- | ------------- | ------------------------ | --------------------- | ----------- | ----------------- |
| **ToolCallCard**          | 聊天区 inline    | 纯 React DOM              | Agent SSE tool\_calls | 只读          | 工具执行状态+结果         |
| **Inline Visualization**  | 聊天区 inline    | `<iframe srcdoc>` 沙箱     | `result.inline_vis`   | 交互（脚本沙箱）    | D3 图表、Three.js 场景 |
| **A2UI**                  | 聊天区 inline    | 原生 React 组件              | `result.a2ui`         | 双向（按钮回调）    | 结构化交互 UI          |
| **FilePanel**             | 右侧「文件」Tab     | img/video/iframe srcDoc  | 沙箱文件 / COS            | 只读预览        | 浏览 agent 产出文件     |
| **Preview**               | 右侧「预览」Tab     | `<iframe src={url}>`     | 沙箱 dev server         | 完全交互（HMR）   | 实时预览 Sites 项目     |
| **Browser**               | 右侧「浏览器」Tab    | `<iframe src={noVNC}>`   | noVNC → 沙箱 Chrome     | VNC 远程操作    | 浏览器自动化可视化         |
| **Widget**                | 右侧「Widget」Tab | `<iframe srcDoc={html}>` | MCP 工具 result.widget  | 双向 JSON-RPC | 交互式工具结果           |
| **Video Timeline Widget** | 右侧「Widget」Tab | Widget 实例 (Twick SDK)    | `timeline_edit` 工具    | 双向 JSON-RPC | 专业多轨视频编辑          |

## 1. ToolCallCard（工具调用结果卡片）

**位置**：嵌入在聊天消息流中

**特点**：

* 纯 React DOM 渲染（**无 iframe**）
* 代码高亮使用 Prism.js
* 支持展开/折叠
* 可包含图片（base64 或 URL）

**触发方式**：Agent SSE 中的 `tool_calls` 事件自动渲染

**展示能力**：

* 文本结果（Markdown 渲染）
* 代码块（语法高亮）
* 图片（截图等）
* 结构化卡片（通过 plugin manifest `ui.toolCallCards` 模板）
* 状态指示器（进行中/成功/失败）

**适用场景**：工具执行中间状态展示、搜索结果、简短文本回答、截图展示

## 2. Inline Visualization（内联可视化）

**位置**：嵌入在聊天消息流中（紧跟 ToolCallCard 之后）

**特点**：

* 使用 `<iframe srcdoc>` 渲染完整 HTML/CSS/JS
* 沙箱化：`sandbox="allow-scripts"`（无网络、无导航、无表单提交）
* 自动高度适应内容（通过 `postMessage` 上报 `document.body.scrollHeight`）
* 支持展开/折叠（默认最大高度 400px，展开后 800px）
* 支持暗色/亮色主题自动适配

**触发方式**：工具返回 `result.inline_vis` 字段（包含 `title`、`html`、可选 `css`）

**通信协议**：

```javascript theme={null}
// 内容 → 宿主（上报高度）
window.parent.postMessage({
  type: "profy-inline-vis-height",
  toolCallId: "...",
  height: document.body.scrollHeight
}, "*")
```

**适用场景**：

* D3/Vega-Lite 数据图表
* Three.js 3D 场景预览
* 统计可视化
* 任何需要 JavaScript 交互的轻量可视化

**与 Widget 的区别**：

* Inline Visualization 嵌入聊天流中（不占右侧面板）
* 无双向 JSON-RPC 通信（只单向上报高度）
* 适用于「看一眼就懂」的可视化，而非需要持续交互的工具

## 3. A2UI（Agent to UI）

**位置**：嵌入在聊天消息流中

**特点**：

* **原生 React 组件**渲染（非 iframe，性能优于 srcdoc）
* 声明式 JSON → 本地 UI 组件映射
* 支持用户交互：按钮点击触发 Action 回传给 Agent
* 16 种内置组件覆盖常见 UI 模式
* 主题、暗色模式自动适配

**触发方式**：Agent 调用 `render_ui` 工具 → 返回 `result.a2ui` 字段

**组件分类**：

| 类别       | 组件                                                                                           |
| -------- | -------------------------------------------------------------------------------------------- |
| 布局       | `Row`, `Column`, `Card`                                                                      |
| 内容       | `Text`, `Image`, `Divider`, `Badge`, `List`, `Table`                                         |
| 交互       | `Button`                                                                                     |
| Profy 业务 | `ExpertCard`, `CreditDisplay`, `PlanBadge`, `StatusIndicator`, `PricingTable`, `ProgressBar` |

**交互循环**：

```
Agent 调用 render_ui(components=[...])
  → 前端渲染原生 React 组件
  → 用户点击 Button(action="upgrade_plan")
  → Action 事件分发到 Agent
  → Agent 处理后续逻辑
```

**适用场景**：

* 结构化信息展示（套餐对比表、状态仪表盘）
* 需要用户确认/选择的交互卡片
* 业务数据展示（积分余额、订阅状态）
* 操作引导（按钮触发下一步）

**与 Inline Visualization 的区别**：

* A2UI 是声明式 JSON，无需编写 HTML/CSS/JS
* 渲染为原生 React 组件（一致性更好，性能更优）
* 支持 Action 回调（真正的双向交互）
* 不支持自由绘图/Canvas/WebGL（受限于预定义组件集）

详细文档参见 [A2UI 组件文档](/zh/documentation/plugins/a2ui)。

## 4. FilePanel（文件面板）

**位置**：右侧工作区「文件」Tab

**特点**：

* 根据文件类型选择渲染方式
* 支持多种格式：图片、视频、音频、PDF、Markdown、代码、HTML/SVG
* HTML/SVG 使用 `<iframe srcDoc>` 渲染（沙箱化）
* 代码文件使用语法高亮

**触发方式**：用户点击文件、Agent 产出文件后自动打开

**渲染方式按文件类型**：

| 文件类型                  | 渲染方式              |
| --------------------- | ----------------- |
| 图片 (png/jpg/gif/webp) | `<img>`           |
| 视频 (mp4/webm)         | `<video>`         |
| 音频 (mp3/wav)          | `<audio>`         |
| PDF                   | PDF.js            |
| Markdown              | react-markdown    |
| 代码                    | Prism.js 高亮       |
| HTML/SVG              | `<iframe srcDoc>` |

**适用场景**：查看 Agent 生成的文件产出物

## 5. Preview（实时预览）

**位置**：右侧工作区「预览」Tab

**特点**：

* 通过 `<iframe src={proxyUrl}>` 连接到沙箱内的 dev server
* 默认端口 5173（TanStack Start / Vite）
* 支持 HMR（热模块替换），代码修改实时反映
* 完全交互式（可点击、滚动、输入）

**触发方式**：Sites 插件的 `open_preview` 工具调用

**适用场景**：Sites 项目开发中的实时预览

## 6. Browser（浏览器面板）

**位置**：右侧工作区「浏览器」Tab

**特点**：

* 通过 noVNC WebSocket 连接沙箱内的 Chrome 桌面
* 展示的是完整的浏览器 GUI（包括地址栏、标签栏）
* 用户可以直接通过 VNC 远程操作

**触发方式**：`browser(action="navigate")` 触发打开

**适用场景**：

* 浏览器自动化过程的可视化观察
* 需要用户介入的操作（CAPTCHA 等）
* 复杂网页交互的调试

## 7. Widget（交互式组件）

**位置**：右侧工作区「Widget」Tab

**特点**：

* 使用 `<iframe srcDoc={html}>` 注入完整 HTML
* 沙箱化：`sandbox="allow-scripts allow-forms"`
* 支持双向 JSON-RPC 通信（iframe ↔ 宿主）
* 可调用宿主提供的 MCP 工具

**触发方式**：MCP 工具返回 `result.widget` 字段

**通信协议**：

```javascript theme={null}
// Widget → 宿主（调用工具）
window.parent.postMessage({
  jsonrpc: "2.0",
  method: "tools/call",
  params: { name: "tool_name", arguments: {...} },
  id: 1
}, "*")

// 宿主 → Widget（返回结果）
window.addEventListener("message", (e) => {
  if (e.data.jsonrpc === "2.0" && e.data.id === 1) {
    console.log(e.data.result)
  }
})
```

**适用场景**：

* 交互式游戏/演示
* 数据可视化仪表盘
* 表单工具
* 任何需要与 Agent 双向通信的富 UI

## 8. Video Timeline Widget（视频时间线编辑器）

**位置**：右侧工作区「Widget」Tab（Widget 的特化实例）

**特点**：

* 基于 Twick SDK 的专业多轨时间线编辑器
* 通过 JSON-RPC bridge 与 Agent 双向通信
* Agent 可通过 `timeline_edit` 工具程序化操作时间线
* 用户可手动拖拽、剪辑、调整片段

**触发方式**：`movie(action="assemble")` 或 `timeline_edit` 工具调用后自动打开

**Agent 操作**：

```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)
```

**适用场景**：

* 专业视频剪辑
* 多轨时间线编排
* 视频片段拼接与转场

详细文档参见 [视频制作文档](/zh/documentation/plugins/video-production)。

## 选择指南

```mermaid theme={null}
graph TD
    A[Agent 产出内容] --> B{需要交互吗?}
    B -->|否| C{是文件吗?}
    B -->|是| D{交互类型?}
    C -->|是| E[FilePanel]
    C -->|否| F{是可视化吗?}
    F -->|是| L[Inline Visualization]
    F -->|否| M[ToolCallCard]
    D -->|结构化 UI 按钮/表单| N[A2UI]
    D -->|自由 HTML + 双向通信| G[Widget]
    D -->|视频时间线编辑| O[Video Timeline Widget]
    D -->|dev server 预览| I[Preview]
    D -->|完整浏览器 GUI| K[Browser]
```

## Plugin 创作者指南

如果你在创建 Plugin，选择输出通道的建议：

1. **简短结果**（\< 500 字符）→ 直接返回文本，渲染为 ToolCallCard
2. **截图/图片**→ 返回 base64 图片，渲染为 ToolCallCard 图片
3. **轻量可视化**（图表/3D 预览）→ 通过 `result.inline_vis` 返回，渲染为 Inline Visualization
4. **结构化交互 UI**（按钮/表格/卡片）→ 通过 `render_ui` 工具 + `result.a2ui` 返回，渲染为 A2UI
5. **生成的文件**→ 写入沙箱文件系统，FilePanel 自动展示
6. **交互式工具 UI**（需要自由 HTML + 双向通信）→ 通过 `result.widget` 返回，渲染为 Widget
7. **实时开发预览**→ 启动 dev server + `open_preview`，渲染为 Preview
8. **浏览器自动化可视化**→ 通过 browser 工具触发，渲染为 Browser
