# 普通聊天按需读取与增量同步 范围为应用登记的普通聊天。独立的只读历史入口继续走原来的上游读取链路。 - 已持久化的列表和详情从 SQLite 生成。旧版本或新建会话缺少摘要时,才补齐摘要;换分页参数不再使已知列表回源。 - 消息页按实际位置覆盖范围读取,本地只存了尾部也可以命中该页,不必先下载完整会话。新回合不清除已经保存的历史覆盖信息。 - 回复完成或实时事件出现缺口时,校对当前会话的详情及最新消息,每页 100 条,遇到已保存的稳定位置即停止。按消息 ID 和内容摘要更新,未变化的消息不重写。 - 同一会话合并并发同步。读取期间收到新事件时,旧结果不能覆盖新修订;同步提交后发送账号隔离的失效通知,客户端再按需读取。 - 已缓存的旧页不等待后台同步。最新页可以等待正在提交的尾部;同步失败仍返回已有本地内容。 - 普通页面刷新不绕过本地缓存。会话操作中的“强制刷新历史”才使用 `X-Yaoyao-Cache: bypass`,完整校对并替换历史。下载失败或分页期间消息总数变化时,不替换已有记录。 - 旧消息删除、重排等改变历史位置的情况保留本地内容,等待明确强制刷新,不把它当作普通尾部追加。 - 模型变化继续由实时事件和进入页面时的必要校验处理,取消每 3 秒无条件读取会话详情。 ## 用户消息身份 - `chat_message_identities` 按账号、Profile 和会话保存正式消息 ID 与 `client_message_id` 的一对一关联;强制刷新、重启后继续保留,会话压缩迁移和删除时同步处理。 - 上游携带客户端 ID 时直接保留。旧版上游缺少 ID 时,仅在历史覆盖完整后,结合已确认的提交回执、运行开始时间、下一次提交边界和完整文本寻找唯一对应记录;未确认、被拒绝、排队或对应关系不唯一时不猜测。该兼容路径要求上游时间落在本地记录的提交窗口内。 - 已有缓存缺失 ID 时,在本地消息读取中恢复关联,无需额外请求上游。前端通过正式 ID 与客户端 ID 合并已有气泡;迟到的发送回执不能覆盖正式消息状态。相同文字的多次独立提交始终保留。 ## 验证 工具生命周期同时覆盖实时事件、持久化投影、历史恢复与各端展示:无调用 ID 的 `tool.generating` 只是进度通知;真实调用按工具 ID 合并。回合结束后,缺少完成回执的工具显示结果未确认,失败结果(包括非零退出码)保留失败。历史快照通过用户消息身份替换已完成回合的临时投影,并保护仍在执行、其后已有排队输入的回合。 真实受影响会话的副本回放中,13 条重复累计的工具显示恢复为 5 次实际调用,残留运行状态为 0。文件目录规则见 [服务端文件访问权限](file-access.md)。 - 1,000 条已缓存消息,20 次历史分页读取不请求上游。 - 新增回复只读取一页尾部;漏掉 130 条消息只补两页;原有消息不重新写入。 - 明确强制刷新才覆盖旧编辑和删除;失败时保留旧记录;并发完成事件提交后再通知客户端。 - 浏览器验证普通重载命中本地、强制刷新回源,以及只读历史和普通聊天的边界。 - 用户消息回归覆盖历史与回执乱序、已有重复缓存、连续相同文本、跨页歧义、重启及强制刷新后的身份保留。 这些请求数来自隔离测试,并非对真实网络耗时的估计。