Skip to content

Undefined v3.18.5

Choose a tag to compare

@github-actions github-actions released this 11 Oct 09:25
· 5 commits to main since this release
v3.18.5
9fde0f5

v3.18.5 会话恢复、消息投递与并发持久化修复

本版本集中修复聊天续接、消息发送和后台任务在切换会话、取消、断线、重启及写入失败时的状态错乱:保留已经完成的投递与提交,避免重复回复、旧响应覆盖新操作,以及界面显示成功但数据尚未保存的问题。

变更内容

  • 聊天恢复与历史一致性:WebChat 只有在任务收尾、历史落盘并释放会话占用后才确认完成,创建任务失败会撤销占用,删除会话与接收新任务按顺序处理。完整任务快照保留正文、工具调用与嵌套 Agent 时间线,Chat 客户端修复断线续接、旧版事件重放和分页恢复;离线期间已经完成的会话也会刷新,旧连接、旧会话和旧请求的迟到结果不会覆盖当前状态。
  • WebUI 与客户端交互:修复切换会话后发送归属错误、旧轮询重复追加正文、迟到历史清空刚发送的消息,以及发送失败覆盖后续草稿的问题。保存连接配置时暂停请求,将未完成上传标记失败并忽略迟到结果,旧缓存迁移失败保留原数据;日志、工作流、表情包编辑和微信登录弹窗隔离各自请求,刷新与翻页保留未保存的编辑。恢复配置失败会保留表单并显示错误,不再误报恢复成功;登录凭据刷新串行执行,避免并发刷新相互失效。
  • 消息投递不再被后续故障误判:微信按每次服务端确认及时记录已发送状态,支持展开嵌套转发;历史、附件登记或使用统计失败不会把已送达内容当作未发送。分片或批量发送已有部分成功、或投递结果无法确认时,微信、抖音、JM 等业务降级不再重发整条内容;仍保留对明确未投递内容的降级。令牌失效、会话暂停、配置错误及明确的连接前失败保留原异常,不再误标为可能送达;认证问题不触发拆分消息的结构降级。微信帐号变更与客户端启停串行,OneBot 重连不再等待消息处理任务阻塞;arXiv 去重按实际平台与投递地址隔离。
  • 配置保存与热更新:整体保存、增量修改、恢复、模板同步和密码更新共用原子写入顺序,同一时刻的备份不会互相覆盖;取消请求会等已开始的写入与必要更新完成。热更新失败可以重试,监听器重启会补读停止窗口内的修改,连续调整轮询间隔不会留下多个监听任务或继续使用旧间隔。内存构建配置不再意外读取本地文件,损坏的 TOML 即使使用 strict=False 也会明确报错。
  • 停止与取消:停止 Bot 先关闭新任务入口,等待已接收的回复、后台任务和持久化收尾,再关闭模型队列与消息通道。新增 [webui].stop_timeout_seconds(环境变量 WEBUI_STOP_TIMEOUT_SECONDS),默认 0 表示等待自然结束,正整数才会在对应秒数后强制终止;停止按钮、关闭 WebUI 和更新前停止共用此规则。取消模型请求会同步清理排队及重试任务,普通群聊队列裁剪保留已启动调用所依赖的子请求。新增 [core].group_llm_queue_max_pending(默认 128,支持热更新),每模型普通群聊 LLM 等待队列满时明确拒绝新请求并清理其等待状态,保留已接收任务与重试;这是排队准入限制,不限制在途调用或总内存,过载时普通自动回复可能结束而不发送消息。
  • 连续消息与工具状态:已经回复完成的投机批次及时结束,后续消息开启新批次,避免把旧输入再次回复;批次取消只作用于对应任务,不会误伤独立的 @ 或拍一拍回复。task_progress 在多轮工具调用间共享,技能热重载保留在途统计;多模态分析缓存使用完整媒体来源、类型与补充指令,避免长链接或 data URL 前缀相同而串用结果。
  • 记忆与知识库:长期记忆和会话数据在落盘成功后才发布新状态,取消会等待已开始的提交,写入失败不会让内存与磁盘各自保留不同版本。知识文件替换先完成新内容读取、嵌入和写入,再清理旧索引;读取、嵌入或新块写入失败时保留旧索引供重试。侧写昵称刷新与史官跳过合并时也会补齐检索索引,索引失败不再提前确认完成;记忆时间筛选统一比较含时区与不含时区的时间。
  • 表情包生命周期:重分析不会覆盖期间的人工编辑、恢复已删除内容或影响同 UID 重新入库的记录;停用、删除与附件缓存失效保持一致,搜索不会返回已停用条目。使用统计失败保留发送成功结果,容量清理跳过刚置顶或修改的候选,删除失败保留可重试记录;异常退出遗留的处理任务会在后续轮询中恢复,正在执行的任务不会被重复调度。
  • 自动化流程:持久化按顺序完成,取消不会让旧快照覆盖新状态;嵌套并行循环只合并本轮修改的变量,避免覆盖同级节点刚产生的输出。loop.times.count=0 正确跳过循环,旧存档的 count:null 兼容默认次数;新建、更新与启用任务仍严格拒绝负数、布尔值、字符串及 null。
  • 文件与附件:统一解析本地 file:// URI,保留中文、空格及原始路径中的百分号;CQ 参数转义与解码保留链接里的逗号、方括号和实体文本。HTTP 压缩响应按传输字节校验完整性、按解压后大小执行容量限制。JM、Bilibili、arXiv 下载及 Python 执行目录在取消后等待后台文件操作结束再清理;JM 配置的会话目录生效,畸形输入和单章异常不再拖垮整次处理。侧写路径与归档解压目标限制在各自目录内,缓存清理拒绝符号链接目录,TAR 解压启用安全过滤。
  • 原生显示与连接:附件下载以独占方式创建文件,避免覆盖同名文件;图片仍显示时保留其 Blob,代码高亮失败回落纯文本,生产构建拆分体积并保留完整语言支持。Console 迁移旧连接时保留协议与 IPv6 地址,Android 生命周期监听即使延迟注册也会在退出后释放。恢复应用时保留刷新途中刚获确认的新任务,同一任务不会重复建立在途 SSE 订阅;迟到旧句柄会关闭,避免覆盖当前订阅或在取消后泄漏。
  • 部署与维护:部署向导中断不再继续写配置,备份名称不冲突,IPv6 服务地址正确加括号;容器模式为 Python 解释器映射宿主 Docker 可见的共享目录,LxMusic 配置变化会触发容器重建。restore_profile.py restore 现在同时恢复侧写并同步检索正文与向量,失败后可用 sync 补齐,执行前须停止机器人及其他写入进程。重嵌入的 --dry-run 在临时副本上读取,不修改源向量库,但仍会调用嵌入 API;侧写恢复的 --dry-run 不写盘、不调用模型。版本脚本支持失败后重跑,补齐全部版本文件与锁文件,并将此前已修改的版本目标纳入提交。

📝 Detailed Changes

🐛 Bug Fixes

  • fix: 修复会话恢复、并发持久化与消息投递(v3.18.5) (#110) (9fde0f5)