@gnai/message-content-renderer 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +273 -27
- package/dist/index.d.ts +1 -0
- package/dist/message-content-renderer.css +1 -1
- package/dist/message-content-renderer.es.js +4046 -4040
- package/dist/message-content-renderer.umd.js +10 -10
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1,38 +1,284 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 光年 AI 智能体对话网页端
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个为光年 AI 智能体打造的现代化网页端对话应用,提供流畅的用户体验和强大的功能特性。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 🎯 项目概述
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- 通过网页 `hostname` 动态识别智能体 ID(例如:从 `gnlab.a.gnlab.com` 中提取 `gnlab` 作为 ID)。
|
|
9
|
-
- 根据 ID 调用 API 接口,获取智能体的详细信息,包括:ID、标题、头像、描述、作者昵称和作者头像。
|
|
10
|
-
- 获取信息后,动态更新网页的 `title` 和 `favicon`。
|
|
7
|
+
这是一个基于 Vue 3 + TypeScript 构建的智能体对话平台,用户可以通过网页与指定的 AI 智能体进行自然对话交互。项目采用组件化架构,具有优秀的响应式设计和流畅的动画效果。
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
- 支持发送纯文本消息。
|
|
14
|
-
- 支持发送图文混合消息。
|
|
15
|
-
- 用户可以上传图片,图片会悬浮在输入框上方。
|
|
16
|
-
- 单次最多支持发送 5 张图片。
|
|
9
|
+
## ✨ 核心功能
|
|
17
10
|
|
|
18
|
-
|
|
19
|
-
- 用户在发起对话时,系统会检查其登录状态(是否存在 `token`)。
|
|
20
|
-
- 如果用户未登录,将在对话窗口内直接展示登录组件 (`Login.vue`),引导用户完成登录。
|
|
21
|
-
- 登录及用户信息相关的逻辑已完成,可直接复用。
|
|
11
|
+
### 🤖 智能体识别与信息加载
|
|
22
12
|
|
|
23
|
-
|
|
13
|
+
- **动态 ID 解析**: 从域名自动提取智能体 ID(如 `gnlab.a.gnlab.com` → `gnlab`)
|
|
14
|
+
- **智能体信息展示**: 加载并展示智能体的头像、名称、描述、作者信息
|
|
15
|
+
- **动态页面配置**: 根据智能体信息自动更新网页标题和 favicon
|
|
16
|
+
- **加载状态管理**: 提供优雅的加载动画和错误处理
|
|
24
17
|
|
|
25
|
-
###
|
|
18
|
+
### 💬 智能对话系统
|
|
26
19
|
|
|
27
|
-
-
|
|
20
|
+
- **文本对话**: 支持纯文本消息的发送与接收
|
|
21
|
+
- **图文混合**: 支持文本与图片的混合消息
|
|
22
|
+
- **图片上传**: 最多支持 5 张图片上传,提供预览和删除功能
|
|
23
|
+
- **消息重试**: 失败消息支持重新发送
|
|
24
|
+
- **Markdown 渲染**: 支持 Markdown 格式的消息展示
|
|
25
|
+
- **多媒体支持**: 支持图片、视频、音频、文件等多种消息类型
|
|
26
|
+
|
|
27
|
+
### 🔐 用户认证系统
|
|
28
|
+
|
|
29
|
+
- **登录状态检测**: 自动检查用户登录状态
|
|
30
|
+
- **无感登录**: 未登录时在对话窗口内展示登录组件
|
|
31
|
+
- **Token 管理**: 完善的用户认证和状态管理
|
|
32
|
+
- **用户信息**: 自动获取和展示用户信息
|
|
33
|
+
|
|
34
|
+
### 🎨 现代化界面
|
|
35
|
+
|
|
36
|
+
- **Apple 风格设计**: 简洁大方的视觉设计,大量留白
|
|
37
|
+
- **响应式布局**: 完美适配桌面端和移动端
|
|
38
|
+
- **智能面板**: 可展开/收起的智能体信息面板
|
|
39
|
+
- **流畅动画**: 平滑的过渡效果和交互动画
|
|
40
|
+
- **键盘快捷键**: 提供高效的键盘操作支持
|
|
41
|
+
|
|
42
|
+
## 🏗️ 技术架构
|
|
43
|
+
|
|
44
|
+
### 技术栈
|
|
45
|
+
|
|
46
|
+
- **前端框架**: Vue 3 (Composition API)
|
|
28
47
|
- **状态管理**: Pinia
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
48
|
+
- **类型检查**: TypeScript
|
|
49
|
+
- **样式方案**: Less + CSS 变量
|
|
50
|
+
- **图标库**: Iconify (@iconify/vue)
|
|
51
|
+
- **HTTP 客户端**: Axios
|
|
52
|
+
- **构建工具**: Vite
|
|
53
|
+
- **代码格式化**: Prettier
|
|
54
|
+
|
|
55
|
+
### 项目结构
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
src/
|
|
59
|
+
├── components/ # 15+ 个高内聚组件
|
|
60
|
+
│ ├── AgentPanel.vue # 智能体信息面板
|
|
61
|
+
│ ├── ChatArea.vue # 对话区域容器
|
|
62
|
+
│ ├── MessageItem.vue # 单条消息组件
|
|
63
|
+
│ ├── MessageList.vue # 消息列表
|
|
64
|
+
│ ├── InputArea.vue # 输入区域
|
|
65
|
+
│ ├── ImagePreview.vue # 图片预览
|
|
66
|
+
│ ├── LoginModal.vue # 登录弹窗
|
|
67
|
+
│ └── 更多组件...
|
|
68
|
+
├── stores/ # Pinia 状态管理
|
|
69
|
+
│ ├── agent.ts # 智能体状态
|
|
70
|
+
│ ├── chat.ts # 对话状态
|
|
71
|
+
│ └── user.ts # 用户状态
|
|
72
|
+
├── utils/ # 工具函数
|
|
73
|
+
│ ├── agent.ts # 智能体相关
|
|
74
|
+
│ ├── request.ts # HTTP 请求
|
|
75
|
+
│ └── app.ts # 通用工具
|
|
76
|
+
├── lib/ # 可复用库组件
|
|
77
|
+
│ ├── MessageContentRenderer.vue # 消息内容渲染器
|
|
78
|
+
│ └── ImageViewer.vue # 图片查看器
|
|
79
|
+
├── App.vue # 主应用组件
|
|
80
|
+
├── Login.vue # 登录组件
|
|
81
|
+
├── main.ts # 应用入口
|
|
82
|
+
└── main.css # 全局样式
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 设计规范
|
|
86
|
+
|
|
87
|
+
- **配色方案**: 浅色主题,蓝色强调色
|
|
88
|
+
- **间距系统**: 4px 基础单位的规范化间距
|
|
89
|
+
- **圆角规范**: 6px-20px 的柔和圆角
|
|
90
|
+
- **动画系统**: 150ms-300ms 的流畅过渡
|
|
91
|
+
|
|
92
|
+
## 🚀 快速开始
|
|
93
|
+
|
|
94
|
+
### 环境要求
|
|
95
|
+
|
|
96
|
+
- Node.js ^20.19.0 || >=22.12.0
|
|
97
|
+
- pnpm 包管理器
|
|
98
|
+
|
|
99
|
+
### 安装与启动
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 克隆项目
|
|
103
|
+
git clone <repository-url>
|
|
104
|
+
cd gnai-angent-web
|
|
105
|
+
|
|
106
|
+
# 安装依赖
|
|
107
|
+
pnpm install
|
|
108
|
+
|
|
109
|
+
# 启动开发服务器
|
|
110
|
+
pnpm dev
|
|
111
|
+
|
|
112
|
+
# 构建生产版本
|
|
113
|
+
pnpm build
|
|
114
|
+
|
|
115
|
+
# 预览生产版本
|
|
116
|
+
pnpm preview
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 开发命令
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# 类型检查
|
|
123
|
+
pnpm type-check
|
|
124
|
+
|
|
125
|
+
# 代码格式化
|
|
126
|
+
pnpm format
|
|
127
|
+
|
|
128
|
+
# 构建库组件(MessageContentRenderer)
|
|
129
|
+
pnpm run build:lib
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 📱 使用方式
|
|
133
|
+
|
|
134
|
+
### 智能体部署
|
|
135
|
+
|
|
136
|
+
应用会自动从域名解析智能体 ID:
|
|
137
|
+
|
|
138
|
+
- `demo.a.gnlab.com` → 智能体 ID: `demo`
|
|
139
|
+
- `gnlab.a.gnlab.com` → 智能体 ID: `gnlab`
|
|
140
|
+
- `localhost:5173` → 开发环境默认使用 `demo`
|
|
141
|
+
|
|
142
|
+
### 对话功能
|
|
143
|
+
|
|
144
|
+
1. **发送消息**: 输入文本后按 Enter 或点击发送按钮
|
|
145
|
+
2. **图片上传**: 点击图片按钮选择最多 5 张图片
|
|
146
|
+
3. **新对话**: 使用 `Cmd/Ctrl + K` 快捷键
|
|
147
|
+
4. **切换面板**: 使用 `Cmd/Ctrl + I` 快捷键
|
|
148
|
+
|
|
149
|
+
### 移动端体验
|
|
150
|
+
|
|
151
|
+
- 面板默认收起,点击边缘按钮展开
|
|
152
|
+
- 支持侧滑手势操作
|
|
153
|
+
- 适配各种移动设备尺寸
|
|
154
|
+
|
|
155
|
+
## 📦 库组件发布
|
|
156
|
+
|
|
157
|
+
本项目包含可复用的 `MessageContentRenderer` 库组件:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# 构建库组件
|
|
161
|
+
pnpm run build:lib
|
|
162
|
+
|
|
163
|
+
# 发布到 npm
|
|
164
|
+
npm login
|
|
165
|
+
npm publish
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### MessageContentRenderer 特性
|
|
169
|
+
|
|
170
|
+
- 支持多种消息类型(文本、图片、文件、音频、视频)
|
|
171
|
+
- Markdown 渲染支持
|
|
172
|
+
- 响应式设计
|
|
173
|
+
- 类型安全的 Vue 组件
|
|
174
|
+
|
|
175
|
+
## 🔧 配置说明
|
|
176
|
+
|
|
177
|
+
### 环境变量
|
|
178
|
+
|
|
179
|
+
项目支持以下环境变量配置:
|
|
180
|
+
|
|
181
|
+
- `VITE_API_BASE`: API 基础地址
|
|
182
|
+
- `VITE_APP_ENV`: 应用环境标识
|
|
183
|
+
|
|
184
|
+
### 构建配置
|
|
185
|
+
|
|
186
|
+
- `vite.config.ts`: 主应用构建配置
|
|
187
|
+
- `vite.config.lib.ts`: 库组件构建配置
|
|
188
|
+
- `tsconfig.json`: TypeScript 配置
|
|
189
|
+
|
|
190
|
+
## 🎨 自定义开发
|
|
191
|
+
|
|
192
|
+
### 主题定制
|
|
193
|
+
|
|
194
|
+
通过 CSS 变量系统可以轻松定制主题:
|
|
195
|
+
|
|
196
|
+
```css
|
|
197
|
+
:root {
|
|
198
|
+
--color-primary: #007aff;
|
|
199
|
+
--color-bg: #f5f5f7;
|
|
200
|
+
--color-text: #1d1d1f;
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 组件扩展
|
|
205
|
+
|
|
206
|
+
所有组件都遵循高内聚低耦合原则,易于扩展和维护:
|
|
207
|
+
|
|
208
|
+
1. 新增功能建议创建独立组件
|
|
209
|
+
2. 使用 TypeScript 提供类型安全
|
|
210
|
+
3. 遵循现有的设计规范和命名约定
|
|
211
|
+
|
|
212
|
+
## 📋 API 接口
|
|
213
|
+
|
|
214
|
+
### 智能体接口
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// 获取智能体详情
|
|
218
|
+
GET /api/athena/v1/chatbot/detail?pid={agentId}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 对话接口
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// 发送消息
|
|
225
|
+
POST /api/athena/v1/chat/send
|
|
226
|
+
{
|
|
227
|
+
agentId: string,
|
|
228
|
+
message: string,
|
|
229
|
+
images?: string[]
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 🧪 测试与调试
|
|
234
|
+
|
|
235
|
+
### 开发模式
|
|
236
|
+
|
|
237
|
+
- 热重载开发服务器
|
|
238
|
+
- TypeScript 实时检查
|
|
239
|
+
- ESLint 代码检查
|
|
240
|
+
- Prettier 代码格式化
|
|
241
|
+
|
|
242
|
+
### 浏览器支持
|
|
243
|
+
|
|
244
|
+
- Chrome / Edge (最新版本)
|
|
245
|
+
- Firefox (最新版本)
|
|
246
|
+
- Safari (最新版本)
|
|
247
|
+
- 移动端浏览器
|
|
248
|
+
|
|
249
|
+
## 📈 性能优化
|
|
250
|
+
|
|
251
|
+
- **代码分割**: 基于路由的代码分割
|
|
252
|
+
- **图片懒加载**: 大图片的懒加载处理
|
|
253
|
+
- **虚拟滚动**: 大量消息的性能优化(可选)
|
|
254
|
+
- **缓存策略**: 智能体信息本地缓存
|
|
255
|
+
|
|
256
|
+
## 🤝 贡献指南
|
|
257
|
+
|
|
258
|
+
1. Fork 项目
|
|
259
|
+
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
|
260
|
+
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
|
261
|
+
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
262
|
+
5. 开启 Pull Request
|
|
263
|
+
|
|
264
|
+
## 📄 许可证
|
|
265
|
+
|
|
266
|
+
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
|
|
267
|
+
|
|
268
|
+
## 🙏 致谢
|
|
269
|
+
|
|
270
|
+
- Vue.js 团队
|
|
271
|
+
- Pinia 团队
|
|
272
|
+
- 所有开源库的贡献者
|
|
273
|
+
|
|
274
|
+
## 📞 联系方式
|
|
275
|
+
|
|
276
|
+
如有问题或建议,请通过以下方式联系:
|
|
277
|
+
|
|
278
|
+
- 提交 GitHub Issues
|
|
279
|
+
- 查看开发文档: `DEVELOPMENT.md`
|
|
280
|
+
- 快速指南: `QUICKSTART.md`
|
|
33
281
|
|
|
34
|
-
|
|
282
|
+
---
|
|
35
283
|
|
|
36
|
-
|
|
37
|
-
`npm login`
|
|
38
|
-
`npm publish`
|
|
284
|
+
✨ **由光年 AI 提供技术支持** | 🚀 **立即体验智能对话新境界**
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.vjs-tree-brackets{cursor:pointer}.vjs-tree-brackets:hover{color:#1890ff}.vjs-check-controller{position:absolute;left:0}.vjs-check-controller.is-checked .vjs-check-controller-inner{background-color:#1890ff;border-color:#0076e4}.vjs-check-controller.is-checked .vjs-check-controller-inner.is-checkbox:after{transform:rotate(45deg) scaleY(1)}.vjs-check-controller.is-checked .vjs-check-controller-inner.is-radio:after{transform:translate(-50%,-50%) scale(1)}.vjs-check-controller .vjs-check-controller-inner{display:inline-block;position:relative;border:1px solid #bfcbd9;border-radius:2px;vertical-align:middle;box-sizing:border-box;width:16px;height:16px;background-color:#fff;z-index:1;cursor:pointer;transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.vjs-check-controller .vjs-check-controller-inner:after{box-sizing:content-box;content:"";border:2px solid #fff;border-left:0;border-top:0;height:8px;left:4px;position:absolute;top:1px;transform:rotate(45deg) scaleY(0);width:4px;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;transform-origin:center}.vjs-check-controller .vjs-check-controller-inner.is-radio{border-radius:100%}.vjs-check-controller .vjs-check-controller-inner.is-radio:after{border-radius:100%;height:4px;background-color:#fff;left:50%;top:50%}.vjs-check-controller .vjs-check-controller-original{opacity:0;outline:none;position:absolute;z-index:-1;inset:0;margin:0}.vjs-carets{position:absolute;right:0;cursor:pointer}.vjs-carets svg{transition:transform .3s}.vjs-carets:hover{color:#1890ff}.vjs-carets-close{transform:rotate(-90deg)}.vjs-tree-node{display:flex;position:relative;line-height:20px}.vjs-tree-node.has-carets{padding-left:15px}.vjs-tree-node.has-carets.has-selector,.vjs-tree-node.has-selector{padding-left:30px}.vjs-tree-node.is-highlight,.vjs-tree-node:hover{background-color:#e6f7ff;border-radius:4px}.vjs-tree-node.is-highlight .vjs-tree-node-actions,.vjs-tree-node:hover .vjs-tree-node-actions{display:block}.vjs-tree-node .vjs-indent{display:flex;position:relative}.vjs-tree-node .vjs-indent-unit.has-line{border-left:1px dashed #bfcbd9}.vjs-tree-node .vjs-tree-node-actions{display:none;position:absolute;right:0;top:0;padding:0 4px;background-color:#e6f7ff;border-radius:4px}.vjs-tree-node .vjs-tree-node-actions .vjs-tree-node-actions-item{cursor:pointer}.vjs-tree-node .vjs-tree-node-actions .vjs-tree-node-actions-item:hover{color:#1890ff}.vjs-tree-node.dark.is-highlight,.vjs-tree-node.dark .vjs-tree-node-actions,.vjs-tree-node.dark:hover{background-color:#2e4558}.vjs-node-index{position:absolute;right:100%;margin-right:4px;-webkit-user-select:none;user-select:none}.vjs-colon{white-space:pre}.vjs-comment{color:#bfcbd9}.vjs-value{word-break:break-word}.vjs-value-null,.vjs-value-undefined{color:#d55fde}.vjs-value-boolean,.vjs-value-number{color:#1d8ce0}.vjs-value-string{color:#13ce66}.vjs-tree{font-family:Monaco,Menlo,Consolas,Bitstream Vera Sans Mono,monospace;font-size:14px;text-align:left}.vjs-tree.is-virtual{overflow:auto}.vjs-tree.is-virtual .vjs-tree-node{white-space:nowrap}.image-viewer[data-v-92c159ee]{position:fixed;inset:0;background:#000000e6;display:flex;align-items:center;justify-content:center;z-index:2000;padding:32px;cursor:zoom-out}.close-button[data-v-92c159ee]{position:fixed;top:24px;right:24px;width:48px;height:48px;display:flex;align-items:center;justify-content:center;color:#fff;background:#00000080;border-radius:50%;cursor:pointer;transition:all .15s cubic-bezier(.4,0,.2,1);z-index:2001}.close-button[data-v-92c159ee]:hover{background:#000c;transform:scale(1.1)}.close-button svg[data-v-92c159ee]{width:24px;height:24px}.viewer-content[data-v-92c159ee]{max-width:90%;max-height:90%;display:flex;align-items:center;justify-content:center;cursor:default}.viewer-content img[data-v-92c159ee]{max-width:100%;max-height:90vh;object-fit:contain;border-radius:10px;box-shadow:0 8px 32px #00000080}.viewer-enter-active[data-v-92c159ee],.viewer-leave-active[data-v-92c159ee]{transition:opacity .2s cubic-bezier(.4,0,.2,1)}.viewer-enter-from[data-v-92c159ee],.viewer-leave-to[data-v-92c159ee]{opacity:0}@media(max-width:768px){.image-viewer[data-v-92c159ee]{padding:16px}.close-button[data-v-92c159ee]{top:16px;right:16px;width:40px;height:40px}.close-button svg[data-v-92c159ee]{width:20px;height:20px}.viewer-content img[data-v-92c159ee]{border-radius:6px}}.
|
|
1
|
+
.vjs-tree-brackets{cursor:pointer}.vjs-tree-brackets:hover{color:#1890ff}.vjs-check-controller{position:absolute;left:0}.vjs-check-controller.is-checked .vjs-check-controller-inner{background-color:#1890ff;border-color:#0076e4}.vjs-check-controller.is-checked .vjs-check-controller-inner.is-checkbox:after{transform:rotate(45deg) scaleY(1)}.vjs-check-controller.is-checked .vjs-check-controller-inner.is-radio:after{transform:translate(-50%,-50%) scale(1)}.vjs-check-controller .vjs-check-controller-inner{display:inline-block;position:relative;border:1px solid #bfcbd9;border-radius:2px;vertical-align:middle;box-sizing:border-box;width:16px;height:16px;background-color:#fff;z-index:1;cursor:pointer;transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.vjs-check-controller .vjs-check-controller-inner:after{box-sizing:content-box;content:"";border:2px solid #fff;border-left:0;border-top:0;height:8px;left:4px;position:absolute;top:1px;transform:rotate(45deg) scaleY(0);width:4px;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;transform-origin:center}.vjs-check-controller .vjs-check-controller-inner.is-radio{border-radius:100%}.vjs-check-controller .vjs-check-controller-inner.is-radio:after{border-radius:100%;height:4px;background-color:#fff;left:50%;top:50%}.vjs-check-controller .vjs-check-controller-original{opacity:0;outline:none;position:absolute;z-index:-1;inset:0;margin:0}.vjs-carets{position:absolute;right:0;cursor:pointer}.vjs-carets svg{transition:transform .3s}.vjs-carets:hover{color:#1890ff}.vjs-carets-close{transform:rotate(-90deg)}.vjs-tree-node{display:flex;position:relative;line-height:20px}.vjs-tree-node.has-carets{padding-left:15px}.vjs-tree-node.has-carets.has-selector,.vjs-tree-node.has-selector{padding-left:30px}.vjs-tree-node.is-highlight,.vjs-tree-node:hover{background-color:#e6f7ff;border-radius:4px}.vjs-tree-node.is-highlight .vjs-tree-node-actions,.vjs-tree-node:hover .vjs-tree-node-actions{display:block}.vjs-tree-node .vjs-indent{display:flex;position:relative}.vjs-tree-node .vjs-indent-unit.has-line{border-left:1px dashed #bfcbd9}.vjs-tree-node .vjs-tree-node-actions{display:none;position:absolute;right:0;top:0;padding:0 4px;background-color:#e6f7ff;border-radius:4px}.vjs-tree-node .vjs-tree-node-actions .vjs-tree-node-actions-item{cursor:pointer}.vjs-tree-node .vjs-tree-node-actions .vjs-tree-node-actions-item:hover{color:#1890ff}.vjs-tree-node.dark.is-highlight,.vjs-tree-node.dark .vjs-tree-node-actions,.vjs-tree-node.dark:hover{background-color:#2e4558}.vjs-node-index{position:absolute;right:100%;margin-right:4px;-webkit-user-select:none;user-select:none}.vjs-colon{white-space:pre}.vjs-comment{color:#bfcbd9}.vjs-value{word-break:break-word}.vjs-value-null,.vjs-value-undefined{color:#d55fde}.vjs-value-boolean,.vjs-value-number{color:#1d8ce0}.vjs-value-string{color:#13ce66}.vjs-tree{font-family:Monaco,Menlo,Consolas,Bitstream Vera Sans Mono,monospace;font-size:14px;text-align:left}.vjs-tree.is-virtual{overflow:auto}.vjs-tree.is-virtual .vjs-tree-node{white-space:nowrap}.image-viewer[data-v-92c159ee]{position:fixed;inset:0;background:#000000e6;display:flex;align-items:center;justify-content:center;z-index:2000;padding:32px;cursor:zoom-out}.close-button[data-v-92c159ee]{position:fixed;top:24px;right:24px;width:48px;height:48px;display:flex;align-items:center;justify-content:center;color:#fff;background:#00000080;border-radius:50%;cursor:pointer;transition:all .15s cubic-bezier(.4,0,.2,1);z-index:2001}.close-button[data-v-92c159ee]:hover{background:#000c;transform:scale(1.1)}.close-button svg[data-v-92c159ee]{width:24px;height:24px}.viewer-content[data-v-92c159ee]{max-width:90%;max-height:90%;display:flex;align-items:center;justify-content:center;cursor:default}.viewer-content img[data-v-92c159ee]{max-width:100%;max-height:90vh;object-fit:contain;border-radius:10px;box-shadow:0 8px 32px #00000080}.viewer-enter-active[data-v-92c159ee],.viewer-leave-active[data-v-92c159ee]{transition:opacity .2s cubic-bezier(.4,0,.2,1)}.viewer-enter-from[data-v-92c159ee],.viewer-leave-to[data-v-92c159ee]{opacity:0}@media(max-width:768px){.image-viewer[data-v-92c159ee]{padding:16px}.close-button[data-v-92c159ee]{top:16px;right:16px;width:40px;height:40px}.close-button svg[data-v-92c159ee]{width:20px;height:20px}.viewer-content img[data-v-92c159ee]{border-radius:6px}}.content-text[data-v-011ca0f4]{font-size:15px;line-height:1.6;color:#1d1d1f;background:#fff;border-radius:10px;padding:10px 14px;display:inline-block;max-width:100%}.content-text[data-v-011ca0f4] p{margin:0 0 8px;white-space:pre-wrap;word-wrap:break-word}.content-text[data-v-011ca0f4] p:last-child{margin-bottom:0}.content-text[data-v-011ca0f4] code{background:#fff;padding:2px 6px;border-radius:4px;font-family:Courier New,monospace;font-size:14px}.content-text[data-v-011ca0f4] pre{background:#fff;padding:16px;border-radius:10px;overflow-x:auto;margin:8px 0}.content-text[data-v-011ca0f4] pre code{background:none;padding:0}.content-text[data-v-011ca0f4] a{color:#007aff;text-decoration:none}.content-text[data-v-011ca0f4] a:hover{text-decoration:underline}.content-text[data-v-011ca0f4] ul,.content-text[data-v-011ca0f4] ol{margin:8px 0;padding-left:32px}.content-text[data-v-011ca0f4] blockquote{border-left:4px solid #d2d2d7;padding-left:16px;margin:8px 0;color:#6e6e73}.content-text.role-user[data-v-011ca0f4]{background:var(--color-primary);color:#fff}.content-text.role-user[data-v-011ca0f4] a{color:#fff}.content-file[data-v-24190b61]{display:inline-flex;align-items:center;gap:8px;padding:8px 16px;background:#fff;border:1px solid #d2d2d7;border-radius:10px;cursor:pointer;transition:all .15s cubic-bezier(.4,0,.2,1)}.content-file[data-v-24190b61]:hover{background:#f5f5f7;border-color:#007aff}.content-file .file-icon[data-v-24190b61]{width:20px;height:20px;color:#6e6e73}.content-file .file-name[data-v-24190b61]{font-size:14px;color:#1d1d1f;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.content-file .download-icon[data-v-24190b61]{width:16px;height:16px;color:#007aff}@media(max-width:768px){.content-file .file-name[data-v-24190b61]{max-width:150px}}.message-image[data-v-24952cda]{display:block;max-width:300px;width:auto;height:220px;border-radius:10px;object-fit:cover;cursor:pointer;transition:transform .2s cubic-bezier(.4,0,.2,1)}.message-image[data-v-24952cda]:hover{transform:scale(1.02)}.message-image.is-full-width[data-v-24952cda]{width:100%;max-width:100%}@media(max-width:768px){.message-image[data-v-24952cda]{max-width:200px;height:180px}}.message-video[data-v-28c3e763]{display:block;max-width:100%;height:220px;border-radius:10px}.message-video.is-full-width[data-v-28c3e763]{width:100%}@media(max-width:768px){.message-video[data-v-28c3e763]{height:180px}}.message-audio[data-v-c0d42074]{max-width:100%;height:40px}.message-content-renderer[data-v-adfc2d98]{display:inline-flex;max-width:100%}.content-user-message[data-v-adfc2d98]{display:flex;flex-direction:column;gap:16px;align-items:flex-end}.files-grid[data-v-adfc2d98]{display:inline-flex;flex-direction:column;align-items:flex-end;gap:8px}.content-medialib .json-viewer[data-v-adfc2d98]{background:#fff;padding:16px;border-radius:10px;font-size:13px;max-height:400px;overflow:auto}
|