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

5.9 KiB
Raw Blame History

Swipe 功能测试指南

测试场景

场景1首次重roll消息没有swipes数组

初始状态:

message = {
  id: "ai_123456",
  floor: 2,
  mes: "这是AI的第一次回复",
  is_user: false,
  // 没有 swipes 字段
}

执行重roll后

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数组

初始状态:

message = {
  id: "ai_123456",
  floor: 2,
  mes: "这是AI的第二次回复",
  is_user: false,
  swipes: [
    "这是AI的第一次回复",
    "这是AI的第二次回复"
  ],
  swipe_id: 1
}

执行重roll后

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

初始状态:

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 事件(流式输出)

if (isReroll) {
  // ✅ 重roll模式不更新 mes只在内部累积 assistantMessage
  // mes 保持不变,直到 complete 事件才更新
} else {
  // 正常模式:更新新创建的消息
  set((state) => ({
    messages: state.messages.map((msg) =>
      msg.id === newMessageId ? { ...msg, mes: assistantMessage } : msg
    )
  }));
}

complete 事件(生成完成)

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

// 确定当前显示的消息内容
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