fix: preserve interaction replies across chat recovery

This commit is contained in:
2026-10-29 17:53:33 +08:00
parent fbe273e90a
commit 52681a8451
38 changed files with 1623 additions and 314 deletions
+10
View File
@@ -546,3 +546,13 @@ UI 分页只影响读取窗口,服务端继续保存完整消息并从完整
主题是当前用户在个人/业务项目范围内的会话组织单元,与业务 `project_id` 独立。`GET/POST /api/v1/topics` 读取/创建主题,`PATCH/DELETE /api/v1/topics/:topic_id` 重命名/移除主题,`PATCH /api/v1/session/:session_id/topic` 以 `topic_id`(UUID 或 null)调整会话归属。主题名 1–80 字符,当前主题列表存于 `SESSION_METADATA_STORAGE_DIR/topics/<scope-hash>.json`,与元数据目录一起持久化。删除主题保留会话,遗留成员 ID 在读取时视为未分类;不会改写业务项目、原生会话或授权。旧会话默认未分类,无需迁移。普通会话和任务协作可归类,后台任务执行会话不进入用户主题。
`POST /session` 或首次 `/responses` 的 `tjwater.topic_id` 可指定已授权范围内的主题;后续续聊沿用原会话,移动使用上述独立接口。主题只组织记录,本轮不自动拼接其他会话或引入主题共享指令/附件。正文搜索在通过所有权校验的记录内读取完整消息 JSON(活动会话使用当前运行消息),匹配可见文本而非工具输入或推理;分页仍按更新时间及 ID 排序,不另建搜索服务。
## 可恢复提问与回答展示
支持 `host-question@1` 的客户端使用自有 `ask_user` 提问。宿主在会话 `chat/interaction-requests.json` 保存问题、选项草稿、已提交答案和固定消息 ID 的续跑记录;切换会话不取消提问。文件最多 2 MiB、1000 个请求,不保存登录凭据。接口位于 `/api/v1/session/:session_id/interactions`,提供列表、单项、草稿、reply/skip/cancel/resume;保存答案与模型继续分别显示状态。续跑通过现有 `/responses` 的 `tjwater.interaction_id` 使用服务端答案,不接受调用者替换答案文字。
续跑的用户消息保留同一个 `delivery.native_message_id`,保存可读文本及 `data-interaction_reply` 已提交回答快照;给模型的协议前缀仅用于推理输入。会话详情、分页和恢复流首次状态按当前会话的投递 ID 投影旧记录,提供相同的回答表示,不猜测文本前缀、不改写历史文件。客户端可在独立提问状态接口返回前还原回答卡片和关联过程,随后按修订更新投递状态。
原生 question 保留兼容入口,新增 `GET /api/v1/session/:session_id/questions/:request_id` 核对状态;原生请求缺失时显示失效,已持久化的回答终态保留。服务重启后,在有效用户授权下核对已保存的续跑记录;固定 ID 已被消费时不重发。无法核实对应的已完成回复时显示继续失败,不能把上一轮回答当作恢复结果。模型服务与插件需要同步更新,现有实例不会因源码修改自动完成发布。
聚焦验证:`bun test tests/sessions/interactionRequest.test.ts tests/routes/hostQuestionStream.test.ts tests/routes/interactionRequestRoutes.test.ts tests/routes/chatInteractionBridge.test.ts tests/runtime/hostQuestion.test.ts`。