Files
SillyTavern_replica/SWIPE_TEST_GUIDE.md
2026-05-06 00:40:18 +08:00

239 lines
5.9 KiB
Markdown
Raw 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.
# Swipe 功能测试指南
## 测试场景
### 场景1首次重roll消息没有swipes数组
**初始状态:**
```javascript
message = {
id: "ai_123456",
floor: 2,
mes: "这是AI的第一次回复",
is_user: false,
// 没有 swipes 字段
}
```
**执行重roll后**
```javascript
message = {
id: "ai_123456",
floor: 2,
mes: "这是AI的第二次回复", // 显示新生成的内容
is_user: false,
swipes: [
"这是AI的第一次回复", // 旧版本
"这是AI的第二次回复" // 新版本
],
swipe_id: 1 // 自动切换到新版本
}
```
**前端显示:**
- 因为有 `swipes` 数组,所以显示 `swipes[1]` = "这是AI的第二次回复"
- 显示 swipe 控制按钮:◀ 2/2 ▶
---
### 场景2第二次重roll消息已有swipes数组
**初始状态:**
```javascript
message = {
id: "ai_123456",
floor: 2,
mes: "这是AI的第二次回复",
is_user: false,
swipes: [
"这是AI的第一次回复",
"这是AI的第二次回复"
],
swipe_id: 1
}
```
**执行重roll后**
```javascript
message = {
id: "ai_123456",
floor: 2,
mes: "这是AI的第三次回复", // 显示新生成的内容
is_user: false,
swipes: [
"这是AI的第一次回复",
"这是AI的第二次回复",
"这是AI的第三次回复" // 新版本
],
swipe_id: 2 // 自动切换到新版本
}
```
**前端显示:**
- 显示 `swipes[2]` = "这是AI的第三次回复"
- 显示 swipe 控制按钮:◀ 3/3 ▶
---
### 场景3用户手动切换swipe
**初始状态:**
```javascript
message = {
id: "ai_123456",
floor: 2,
mes: "这是AI的第三次回复",
is_user: false,
swipes: [
"这是AI的第一次回复",
"这是AI的第二次回复",
"这是AI的第三次回复"
],
swipe_id: 2
}
// 用户点击左箭头
currentSwipeId = { 2: 1 } // 切换到第二个版本
```
**前端显示:**
- 因为 `currentSwipeId[2]` 存在,所以使用它而不是 `swipe_id`
- 显示 `swipes[1]` = "这是AI的第二次回复"
- 显示 swipe 控制按钮:◀ 2/3 ▶
---
## 关键逻辑说明
### 1. 后端逻辑ChatBoxSlice.jsx
#### chunk 事件(流式输出)
```javascript
if (isReroll) {
// ✅ 重roll模式不更新 mes只在内部累积 assistantMessage
// mes 保持不变,直到 complete 事件才更新
} else {
// 正常模式:更新新创建的消息
set((state) => ({
messages: state.messages.map((msg) =>
msg.id === newMessageId ? { ...msg, mes: assistantMessage } : msg
)
}));
}
```
#### complete 事件(生成完成)
```javascript
if (isReroll) {
const existingSwipes = msg.swipes || [];
const currentMes = msg.mes; // 当前显示的内容(旧版本)
let updatedSwipes = [...existingSwipes];
// 如果当前 mes 不在 swipes 中,先添加它
if (!updatedSwipes.includes(currentMes)) {
updatedSwipes.push(currentMes);
}
// 添加新生成的内容
updatedSwipes.push(assistantMessage);
return {
...msg,
mes: assistantMessage, // 显示新生成的内容
swipes: updatedSwipes, // 更新 swipes 数组
swipe_id: updatedSwipes.length - 1 // 自动切换到新版本
};
}
```
### 2. 前端逻辑ChatBox.jsx
```javascript
// 确定当前显示的消息内容
let currentMes = message.mes; // 默认使用 mes
let hasSwipes = message.swipes && message.swipes.length > 0;
let currentSwipeIndex = message.swipe_id;
if (hasSwipes) {
// 如果有swipes数组
if (currentSwipeId[message.floor] !== undefined) {
// 如果用户已经切换过版本,使用用户选择的版本
currentSwipeIndex = currentSwipeId[message.floor];
} else {
// 否则使用默认的swipe_id
currentSwipeIndex = message.swipe_id;
}
if (currentSwipeIndex >= 0 && currentSwipeIndex < message.swipes.length) {
currentMes = message.swipes[currentSwipeIndex]; // 从 swipes 中读取
}
}
```
---
## 测试步骤
### 1. 测试首次重roll
1. 发送一条消息等待AI回复
2. 右键点击AI消息选择"重roll"
3. 观察:
- ✅ 流式输出时,消息内容不变(不显示流式过程)
- ✅ 完成后,消息更新为新内容
- ✅ 出现 swipe 控制按钮:◀ 2/2 ▶
- ✅ 点击左箭头可以切换到旧版本
### 2. 测试多次重roll
1. 继续重roll几次
2. 观察:
- ✅ 每次重roll都在 swipes 数组中添加新版本
- ✅ swipe 计数器正确更新2/3, 3/4, 4/5...
- ✅ 可以通过左右箭头切换所有版本
### 3. 测试手动切换
1. 重roll几次后有多个版本
2. 点击左箭头切换到旧版本
3. 观察:
- ✅ 消息内容切换为旧版本
- ✅ swipe 计数器正确更新
- ✅ 再次重roll时新版本添加到末尾
### 4. 测试键盘快捷键
1. 使用左右箭头键切换 swipe
2. 在最后一个版本时按右键触发重roll
3. 观察:
- ✅ 左右键正确切换版本
- ✅ 右键在最后一个版本时触发重roll
- ✅ 重roll后自动切换到新版本
---
## 常见问题排查
### Q1: 重roll后没有出现 swipe 按钮
**原因**swipes 数组没有正确创建
**检查**
- 查看控制台日志:`[ChatBoxStore] 📊 Swipes 更新:`
- 确认 `newCount` 大于 0
- 确认消息对象中有 `swipes` 字段
### Q2: 重roll后显示的是旧内容
**原因**`mes` 字段没有更新
**检查**
- 确认 complete 事件中更新了 `mes: assistantMessage`
- 确认 `assistantMessage` 有正确的内容
### Q3: 切换 swipe 后内容不变
**原因**:前端渲染逻辑有问题
**检查**
- 确认 `currentMes` 正确从 `swipes[currentSwipeIndex]` 读取
- 确认 `currentSwipeIndex` 的值正确
- 确认 `currentSwipeId` 状态正确更新
### Q4: 重roll时看到流式输出覆盖了原内容
**原因**chunk 事件中错误地更新了 `mes`
**检查**
- 确认 chunk 事件中重roll模式不更新 `mes`
- 应该只有正常模式才更新 `mes`