Files
EzVibeR/docs/usage/05-聊天功能.md
Claude Agent 205c57e9b7 Update: Usage
2026-06-20 14:55:47 +08:00

180 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 05 · 聊天功能
聊天面板位于桌宠窗口**右侧**(默认 340 px 宽)。可一键收起让模型占满窗口。
> 第一次启动时聊天面板**默认展开**。改 `chatCollapsed` 状态:在工具栏点 **💬 按钮**(顶部第一个)即可。
## 1. 面板顶部一条
```
[●] [会话下拉(标题 消息数)] [+新建] [✎重命名] [🗑删除] ___ [🔔提醒中心] [🔍搜索导出]
```
| 元素 | 行为 |
|---|---|
| **● 状态点** | 🟢就绪 / 🟠思考中 / 🔴API key 未配置 / ⚪未知 |
| **会话下拉** | 切换已有会话,按 `updated_at` 倒序 |
| **** | 新建一个空会话(标题默认 `对话 MM-DD HH:MM` |
| **✎** | 重命名当前会话(标题 ≤ 40 字符) |
| **🗑** | 删除当前会话(确认弹窗) |
| **🔔** | 跳到「提醒中心」伪会话(激活态高亮) |
| **🔍** | 展开/收起第二行工具栏(搜索 + 导出) |
> 在「提醒中心」时,✎ 和 🗑 **自动禁用**(提醒中心不可重命名/删除)。
## 2. 第二行(点击 🔍 展开)
| 元素 | 行为 |
|---|---|
| **搜索框** | 输入关键字回车 → 当前会话内即时过滤 + 黄色高亮 |
| **🌐 全部** | 弹出全局搜索弹窗(跨会话),点命中条目跳过去 |
| **⬇ MD** | 把当前会话导出为 Markdown 文件,浏览器自动下载 |
| **⬇ JSON** | 把当前会话导出为 JSON 文件,浏览器自动下载 |
## 3. 消息流
按**时间顺序**展示当前会话的所有消息。跨日时**自动插入**灰色圆角日期分割线:
- `今天`(今天的全部消息前)
- `昨天`(昨天的全部消息前)
- `YYYY-MM-DD`(更早的)
> 分割线**不存盘**,是按消息 `ts` 现场算的,所以不用管它,刷新/重启会自动重算。
### 3.1 消息类型与颜色
| 类型 | 来源 | 样式 |
|---|---|---|
| `user` | 你输入 | 右对齐气泡 |
| `assistant` | LLM 回复 | 左对齐气泡 |
| `reminder` | 系统定时提醒 / 手动触发 | 绿松石色气泡(**带 🪧 action_type** |
| `screenshot` | 截图预览(**不持久化** | 中央居中,带"取消/发送给AI"按钮 |
| `system` | 错误提示(如 `[401] API key 无效` | 灰色文字 |
### 3.2 思考气泡
如果 LLM 是 DeepSeek / QwQ / o1 这类带推理的模型,回复里会含 `<think>...</think>` 块。
- **自动**折叠为 `💭 思考过程 ▶` 小标签
- **点击**展开看到完整推理
- 支持多个 `<think>` 块拼接、容错未闭合块、`<thinking>` 标签
- 展开后**再次点击**收起
### 3.3 截图气泡的生命周期
```
[桌宠身体被点击] → 后端截图 → emit('ezvibe:screenshot-captured')
→ 前端 save_chat_image 存盘
→ 推一条 role='screenshot' 消息(含 imagePath / imagePngPath
→ 渲染为带输入框和"取消/发送给AI"按钮的预览气泡
┌─────┴─────┐
[点"取消"] [输入文字 → 点"发送给AI"]
│ │
└─→ 立刻 removeMessage立即消失
└─→ 立刻 removeMessage
└─→ 推一条 role='user' (含 imagePath + 文字)
└─→ 调 invoke('chat', { message, imagePath })
└─→ LLM 回复后推一条 role='assistant'
```
> ⚠️ screenshot 消息**三层防御**不写盘:
> 1. 前端 `removeMessage` 顺手清 `persistTimers` 里的 debounce
> 2. 后端 `append_message` 拒绝 `role=screenshot`
> 3. 后端 `load_session_messages` 跳过 `role=screenshot` 行
> 所以即使你狂点也不会"复活"。
### 3.4 截图发送给 AI 的限制
- 图片后缀必须是 `.png` / `.jpg` / `.jpeg`
- 路径**必须**是 `sessions/<id>/images/xxx` 形式(前端用 `appDataDir() + join` 拼绝对路径)
- **拒绝**绝对路径 / 路径遍历(`..` / 非法 session id
- 文件大小上限 **20 MB**(防止 OOM
- 给 LLM 用的是 **JPEG 预览**80% 质量,几百 KB不是 PNG 原图 — LLM 视觉够用且体积小 10 倍
## 4. 输入框
```
[ 多行文本框 (Enter发送 / Shift+Enter换行) ] [发送]
```
| 行为 | 说明 |
|---|---|
| **Enter** | 发送(前提:输入非空 且 LLM 已配置) |
| **Shift+Enter** | 换行 |
| 空消息 | 发送按钮 disabled |
| LLM 未配置 | placeholder 提示「请先到配置中心填写 API key」 |
| 思考中loading | 整个输入区 disabled状态点变橙色底部出现"桌宠正在思考…" |
## 5. 多会话管理
### 5.1 新建会话
→ 新会话立刻出现在下拉里,自动切过去,标题默认 `对话 MM-DD HH:MM`
### 5.2 切换会话
点下拉选别的会话。**切换时自动加载**该会话的所有历史消息JSONL 读盘)。
### 5.3 自动标题
- 触发条件:**消息数 ≥ 5** 且 **从未生成过标题**
- 时机:前端检测到 `append_message` 返回的新 `msg_count` 达到阈值时,调 `check_title_trigger` + `generate_session_title`
- 实现:异步调 LLM 总结前 5 条消息,输出 ≤ 20 字符短标题(中文 ≤ 12 字 / 英文 ≤ 20 字)
- 失败降级LLM 报错就保持默认 `对话 MM-DD HH:MM`,下次还满足条件会再试
### 5.4 重命名
点 ✎ → 顶部弹输入框 → 输入新标题(≤ 40 字符)→ 回车确认。Esc 取消。
### 5.5 删除
点 🗑 → 确认弹窗 → **整个会话目录** + 索引条目都删(**包括该会话的所有截图**)。
### 5.6 提醒中心(伪会话)
- 标题固定 `🔔 提醒中心`ID 固定 `__reminders__`
- **不可重命名 / 不可删除 / 不参与 LLM 自动标题**
- 所有定时触发的健康提醒**自动写入这个会话**(后端直接落盘,不依赖前端)
- 来新提醒时**自动跳转**到提醒中心视图(即使你正在看别的会话)
## 6. 搜索
### 6.1 当前会话搜索
- 点 🔍 展开第二行工具栏 → 输入关键字
- 即时过滤(输入就过滤)
- 命中片段在气泡里以**黄色背景高亮**`<mark>` 标签)
- 切回空输入恢复显示全部
### 6.2 全局搜索
- 点工具栏 **🌐 全部** 按钮 → 弹出模态框
- 列出所有会话中**包含该关键字**的消息
- 每条命中显示上下文(命中前 20 字 + 命中词 + 命中后 40 字)
- **点任意命中** → 切到那个会话并关弹窗
> 全文搜索是**字面量匹配**`text.find()`),不模糊不忽略大小写。中文按字节匹配。
## 7. 导出
### 7.1 格式
| 格式 | 文件名 | 内容 |
|---|---|---|
| **Markdown** | `<session-id>-<sanitized-title>.md` | 标题 + 元信息 + 每条消息带 emoji 角色(👤/🤖/🔔/📸/⚙️)+ 时间戳 + 文本 + 图片相对路径 |
| **JSON** | `<session-id>-<sanitized-title>.json` | pretty-printed JSON`session: {meta}``messages: [...]` 数组 |
### 7.2 导出位置
**浏览器默认下载目录**。`ExportPayload.suggested_filename` 字段前端会直接用。
### 7.3 提醒中心能不能导出?
**能**。但因为是伪会话,导出内容主要是各种 `reminder` 类型的消息。
## 8. 常见疑问
**Q: 我能同时开几个聊天窗口吗?**
A: 不能。聊天面板是桌宠窗口的一部分(右侧栏),不是独立窗口。多个对话 = 多个会话(用下拉切换)。
**Q: 对话历史存在哪?**
A: 见 [08-数据存储与备份.md](08-数据存储与备份.md)。
**Q: 我清空了 localStorage 会不会丢?**
A: 不会。localStorage 没用,所有会话数据在磁盘。
**Q: 我能编辑 / 删除某条已发送消息吗?**
A: 不能。当前版本没有编辑或单条删除功能(只能删除整个会话)。
---
下一步:[06-健康提醒.md](06-健康提醒.md)。