297 lines
7.8 KiB
Markdown
297 lines
7.8 KiB
Markdown
# Bricks 框架技术文档
|
||
|
||
## 概述
|
||
|
||
本文档描述了 `bricks` 框架中两个核心视图类的实现与使用:`UserInputView` 和 `LlmOut`。这两个类用于处理用户输入和大模型输出内容的可视化展示,支持 Markdown 文本、图像、音频、视频等多种媒体类型。
|
||
|
||
---
|
||
|
||
## 1. `bricks.UserInputView`
|
||
|
||
### 类定义
|
||
```javascript
|
||
bricks.UserInputView = class extends bricks.VBox
|
||
```
|
||
|
||
### 功能说明
|
||
将用户的输入字段(如文本、图片、音视频等)转换为结构化的 Markdown 内容进行展示,并独立嵌入音视频播放器组件。
|
||
|
||
- 所有非音视频字段以代码块形式显示。
|
||
- 图像字段以 Markdown 图像语法渲染。
|
||
- 视频和音频字段通过专用播放器组件独立展示。
|
||
|
||
---
|
||
|
||
### 构造函数
|
||
```javascript
|
||
constructor(opts)
|
||
```
|
||
|
||
#### 参数
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `opts` | Object | 配置选项,继承自 `bricks.VBox` |
|
||
|
||
#### 初始化行为
|
||
- 调用父类构造函数 `super(opts)`
|
||
- 初始化内部变量:
|
||
- `this.v_w`: 视频播放器实例(初始为 `null`)
|
||
- `this.a_w`: 音频播放器实例(初始为 `null`)
|
||
- 调用 `show_input(this.data)` 显示数据
|
||
|
||
---
|
||
|
||
### 方法:`show_input(data)`
|
||
|
||
#### 参数
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `data` | Object | 包含用户输入数据的对象 |
|
||
|
||
#### 处理逻辑
|
||
遍历 `this.input_fields` 中定义的字段配置,根据字段名前缀判断类型并生成相应内容:
|
||
|
||
| 字段前缀 | 处理方式 |
|
||
|---------|----------|
|
||
| `video*` | 创建 `VideoPlayer` 组件,自动播放,宽度 100% |
|
||
| `audio*` | 创建 `AudioPlayer` 组件,自动播放,宽度 100% |
|
||
| `image*` | 在 Markdown 中添加图片语法:`` |
|
||
| 其他 | 使用代码块包裹内容:`\`\`\`\nvalue\n\`\`\`` |
|
||
|
||
> **注意**:字段标签优先使用 `f.label`,若无则使用 `f.name`
|
||
|
||
#### 流程步骤
|
||
1. 初始化空字符串 `mdtext`
|
||
2. 遍历所有输入字段,拼接 Markdown 内容或创建媒体组件
|
||
3. 清除当前所有子组件(`clear_widgets()`)
|
||
4. 创建新的 `MdWidget` 显示 Markdown 内容
|
||
5. 添加音视频组件(如有)
|
||
|
||
#### 示例输出 Markdown
|
||
```markdown
|
||
* 用户提问
|
||
```
|
||
这是用户的输入文本
|
||
```
|
||
|
||
* 示例图片
|
||

|
||
```
|
||
|
||
---
|
||
|
||
### 属性
|
||
| 属性 | 类型 | 描述 |
|
||
|------|------|------|
|
||
| `v_w` | VideoPlayer 或 null | 当前绑定的视频播放器 |
|
||
| `a_w` | AudioPlayer 或 null | 当前绑定的音频播放器 |
|
||
| `input_fields` | Array | 字段定义数组,需在外部设置 |
|
||
| `data` | Object | 输入数据对象 |
|
||
|
||
---
|
||
|
||
## 2. `bricks.LlmOut`
|
||
|
||
### 类定义
|
||
```javascript
|
||
bricks.LlmOut = class extends bricks.VBox
|
||
```
|
||
|
||
### 功能说明
|
||
用于动态渲染大语言模型(LLM)返回的结果数据。支持以下内容类型:
|
||
|
||
- 推理过程文本(thinking / reasoning)
|
||
- 最终回答内容
|
||
- 错误信息
|
||
- 音频响应(URL 或 Base64)
|
||
- 视频响应(URL 或 Base64)
|
||
- 单张或多张图像
|
||
|
||
该组件具备增量更新能力,可通过多次调用 `update()` 累积内容。
|
||
|
||
---
|
||
|
||
### 构造函数
|
||
```javascript
|
||
constructor(opts)
|
||
```
|
||
|
||
#### 参数
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `opts` | Object | 配置选项,继承自 `VBox` |
|
||
|
||
#### 初始化行为
|
||
- 调用父类构造函数
|
||
- 初始化各类媒体组件引用为 `null`
|
||
- 初始化数据缓存属性为空值或空数组
|
||
|
||
#### 初始状态
|
||
```js
|
||
this.rc_w = null; // reasoning widget
|
||
this.c_w = null; // content widget
|
||
this.v_w = null; // video player
|
||
this.i_w = null; // image widgets (not used directly)
|
||
this.a_w = null; // audio player
|
||
this.images = []; // 存储图片 URL 列表
|
||
this.reasoning_content = ''; // 缓存推理内容
|
||
this.content = ''; // 缓存应答内容
|
||
this.error = ''; // 缓存错误信息
|
||
```
|
||
|
||
---
|
||
|
||
### 方法:`update(data)`
|
||
|
||
#### 参数
|
||
| 参数 | 类型 | 必需 | 说明 |
|
||
|------|------|------|------|
|
||
| `data` | Object | 是 | LLM 返回的 JSON 数据 |
|
||
|
||
#### 支持字段
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `reasoning_content` | String | 推理过程文本(可选) |
|
||
| `content` | String | 最终回复文本(可选) |
|
||
| `error` | String | 错误信息(可选) |
|
||
| `audio` | String | 音频资源路径或 Base64 编码(可选) |
|
||
| `video` | String | 视频资源路径或 Base64 编码(可选) |
|
||
| `image` | String 或 Array<String> | 图片资源地址(单个或多个) |
|
||
|
||
---
|
||
|
||
#### 处理逻辑详解
|
||
|
||
##### 🔊 音频处理
|
||
- 若 `audio` 不以 `http` 开头且不包含 `data:audio/` 前缀,则自动封装为 `data:audio/wav;base64,...`
|
||
- 第一次出现时创建 `AudioPlayer`
|
||
- 后续调用会追加新音频(`add_url`)
|
||
|
||
##### 🎥 视频处理
|
||
- 第一次出现创建 `VideoPlayer`
|
||
- 后续更新追加新视频源(`add_url`)
|
||
|
||
##### ❌ 错误处理
|
||
- 将 `data.error` 追加到本地缓存 `this.error`
|
||
- 展示时使用 `resp-error` CSS 类样式化
|
||
|
||
##### 💬 推理内容
|
||
- 追加至 `this.reasoning_content`
|
||
- 使用 `thinking-content` 样式及浅红色背景 (`#f0d0d0`) 区分显示
|
||
|
||
##### ✅ 正常响应内容
|
||
- 追加至 `this.content`
|
||
- 使用 `resp-content` 样式正常展示
|
||
|
||
##### 🖼️ 图像处理
|
||
- 支持单个 URL 或数组
|
||
- 所有图像 URL 被合并进 `this.images` 数组
|
||
- 每张图创建一个 `Image` 组件并添加到容器
|
||
|
||
---
|
||
|
||
#### 渲染顺序
|
||
组件按如下顺序依次添加到界面:
|
||
|
||
1. 错误信息(若有)
|
||
2. 推理内容(若有)
|
||
3. 正常响应内容(若有)
|
||
4. 视频播放器(若有)
|
||
5. 音频播放器(若有)
|
||
6. 所有图片(逐一添加)
|
||
|
||
> **注意**:每次 `update()` 都会先清除已有组件(`clear_widgets()`),再重新构建整个 UI。
|
||
|
||
---
|
||
|
||
### 注册信息
|
||
```js
|
||
bricks.Factory.register('LlmOut', bricks.LlmOut);
|
||
```
|
||
允许通过工厂模式以字符串 `'LlmOut'` 实例化此类。
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
### 示例 1:初始化 UserInputView
|
||
```js
|
||
const userInput = new bricks.UserInputView({
|
||
data: {
|
||
question: "你好吗?",
|
||
image_01: "https://example.com/photo.jpg"
|
||
},
|
||
input_fields: [
|
||
{ name: "question", label: "问题" },
|
||
{ name: "image_01", label: "上传图片" }
|
||
]
|
||
});
|
||
```
|
||
|
||
### 示例 2:更新 LLM 输出
|
||
```js
|
||
const llmView = new bricks.LlmOut();
|
||
|
||
llmView.update({
|
||
reasoning_content: "正在分析用户的问题...",
|
||
audio: "base64encodedstring==",
|
||
image: ["img1.jpg", "img2.jpg"]
|
||
});
|
||
|
||
llmView.update({
|
||
content: "我已经完成分析,这是结果。",
|
||
video: "https://example.com/demo.mp4"
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 依赖说明
|
||
|
||
| 组件 | 用途 |
|
||
|------|------|
|
||
| `bricks.VBox` | 布局容器基类,垂直排列子组件 |
|
||
| `bricks.MdWidget` | 渲染 Markdown 内容 |
|
||
| `bricks.VideoPlayer` | 视频播放组件 |
|
||
| `bricks.AudioPlayer` | 音频播放组件 |
|
||
| `bricks.Image` | 图像显示组件 |
|
||
| `bricks.escapeSpecialChars()` | 工具函数,转义特殊字符防止 XSS |
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. **Base64 音频格式假设**:默认非 HTTP 音频数据为 WAV 格式的 Base64 编码。
|
||
2. **图像数组合并问题**:当前 `concat()` 未正确赋值,应改为:
|
||
```js
|
||
this.images = this.images.concat(data.image);
|
||
```
|
||
3. **增量更新限制**:虽然内容是累积的,但每次都会重绘全部组件,可能影响性能。
|
||
4. **样式依赖**:需要预定义 CSS 类:
|
||
- `resp-error`
|
||
- `thinking-content`
|
||
- `resp-content`
|
||
|
||
---
|
||
|
||
## 待优化建议
|
||
|
||
| 项目 | 建议 |
|
||
|------|------|
|
||
| 图像去重 | 可增加 URL 去重机制 |
|
||
| 媒体并发 | 多个音视频同时播放可能干扰用户体验 |
|
||
| 安全性 | `escapeSpecialChars` 应确保防御 XSS 注入 |
|
||
| 性能 | 大量文本更新时避免频繁 DOM 重绘 |
|
||
|
||
---
|
||
|
||
## 版本信息
|
||
|
||
- 框架:Bricks UI Framework
|
||
- 模块:`UserInputView`, `LlmOut`
|
||
- 作者:系统自动生成文档
|
||
- 时间:2025年4月5日
|
||
|
||
---
|
||
|
||
✅ 文档结束 |