s6-edit-regenerate.md 2.7 KB

S6: 消息编辑 + 重新生成

目标

为 AI 聊天页面(aichat.html)增加两条交互能力:

  1. 双击编辑用户消息:双击用户气泡 → inline 编辑 → Enter 保存 → 重新调 LLM
  2. 重新生成按钮:AI 消息旁出现"重新生成"按钮 → 删除旧回复 → 重新调 LLM

涉及文件

  1. local_db.py — 新增 msg_get()、msg_update()、msg_delete_since()
  2. app.py — 新增 PUT /api/conversations/<conv_id>/messages/<msg_id>、POST /api/conversations/<conv_id>/regenerate
  3. templates/aichat.html — 双击编辑 + 重新生成按钮 UI
  4. 测试文件:test_s6_edit_regenerate.py

数据流

编辑: 双击用户气泡 → contenteditable → Enter → PUT /api/.../messages/<id> {"content":new}
  → 前端重新渲染 → 可选自动触发 regenerate

重新生成: 点击 ⟳ 按钮 → POST /api/.../regenerate
  → 后端删除最后一条 assistant 消息 → 重新调 LLM → 流式返回新回复

步骤

S6a: local_db 新增函数

  • msg_get(msg_id) — 获取单条消息
  • msg_update(msg_id, content) — 更新消息内容
  • msg_delete_since(conv_id, since_id) — 删除指定 ID 之后的消息(用于 regenerate)

S6b: API 路由

  • PUT /api/conversations/<conv_id>/messages/<msg_id> — 编辑消息,校验 role=user
  • POST /api/conversations/<conv_id>/regenerate — 删除最后 AI 回复 → 重新调 LLM → 流式返回

S6c: 前端 UI

  • 用户消息增加 data-msgid 属性,双击触发 inline edit
  • AI 最后一条消息旁显示 ⟳ 重新生成按钮
  • Enter 保存编辑,Escape 取消

验证命令

# 单元测试
python3 test_s6_edit_regenerate.py
# 页面回归
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/chat
# smoketest
python3 test_smoke.py

验收标准(Sprint Contract)

  • [ ] TC1: msg_get(id) 返回正确消息,不存在时返回 None
  • [ ] TC2: msg_update(id, content) 更新后 msg_get 返回新内容
  • [ ] TC3: msg_delete_since(conv_id, since_id) 删除指定 ID 之后的消息(不含 since_id)
  • [ ] TC4: PUT /api/conversations/<conv_id>/messages/<msg_id> 编辑成功返回 200,校验非 user 消息返回 400
  • [ ] TC5: POST /api/conversations/<conv_id>/regenerate 删除最后 AI 消息 → 流式返回新回复
  • [ ] TC6: 页面 /chat 返回 200,用户消息有 data-msgid 属性
  • [ ] TC7: AI 消息区包含 regenerate 相关触发(函数名或按钮元素)
  • [ ] TC8: JS 无转义 bug(style=\\\"、onclick=\")
  • [ ] TC9: smoketest 全部通过(首页/articles/learn/reports 200)

风险

  • 低风险:纯增量,不改现有路由
  • 重新生成需要调用 Hermes:复用现有 call_hermes_stream 逻辑