fix(web): restore conversation clearing

This commit is contained in:
caoqianming 2026-07-31 16:37:39 +08:00
parent 13e3e50371
commit 683bdf993d
4 changed files with 9 additions and 3 deletions

View File

@ -5,6 +5,10 @@
> 所以不是每个版本号都有条目。条目格式 `## <版本> — <日期>`,新条目加在最上面。 > 所以不是每个版本号都有条目。条目格式 `## <版本> — <日期>`,新条目加在最上面。
> 工程口径的完整记录见 `PROGRESS.md` / git log。 > 工程口径的完整记录见 `PROGRESS.md` / git log。
## 0.60.19 — 2026-07-31
- 修复清空对话时可能出现服务器内部错误、导致对话无法清空的问题。
## 0.60.18 — 2026-07-31 ## 0.60.18 — 2026-07-31
- 左侧任务列表默认按最近更新时间排序,继续处理过的对话会自动回到列表前面;创建时间、名称和状态排序仍可手动选择。 - 左侧任务列表默认按最近更新时间排序,继续处理过的对话会自动回到列表前面;创建时间、名称和状态排序仍可手动选择。

View File

@ -2,7 +2,7 @@
> 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9` > 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`
最后更新:2026-07-31(任务列表默认按最近更新时间排序,bump 0.60.18) 最后更新:2026-07-31(修复清空对话 500,bump 0.60.19)
--- ---
@ -23,6 +23,7 @@
### 2026-07-31 ### 2026-07-31
- **07-31 / 0.60.19 / 清空对话 500 修复**:清空接口补查后续标题重置逻辑所需的 `title_source`,修复仅查询 `run_status` 后访问缺失字段导致的 `AttributeError` 与事务回滚;原有 DB 路由用例已覆盖自动标题和人工标题两类清空行为,无 schema、migration、API 或数据语义变化。16 项无 DB 路由测试、Python 编译、致命静态检查与 diff 格式检查通过;未设置 `ZCBOT_TEST_DB_URL`DB 路由测试按安全门控跳过。
- **07-31 / 0.60.18 / 任务列表默认按最近更新时间排序**:普通任务列表的前后端默认排序统一由创建时间倒序改为更新时间倒序,最近继续处理的对话会回到顶部;显式 `ordering=-created_at` 等既有排序参数和全部下拉选项保持兼容。新增默认值、非法参数回退及创建时间兼容 3 项单元测试Python/JavaScript 语法与 diff 格式检查通过;无 schema、migration 或依赖变化。 - **07-31 / 0.60.18 / 任务列表默认按最近更新时间排序**:普通任务列表的前后端默认排序统一由创建时间倒序改为更新时间倒序,最近继续处理的对话会回到顶部;显式 `ordering=-created_at` 等既有排序参数和全部下拉选项保持兼容。新增默认值、非法参数回退及创建时间兼容 3 项单元测试Python/JavaScript 语法与 diff 格式检查通过;无 schema、migration 或依赖变化。
- **07-31 / 0.60.17 / 消息 JSONB NUL 字符兼容**:外部工具从论文、PDF 等来源提取的文本可能夹带真实 NULPython JSON 会编码为 PostgreSQL `jsonb` 无法转换成 text 的 `\u0000`,导致 tool message INSERT 回滚并中断 run。新增递归清洗并在 `Message.payload` ORM 写入边界统一守门,`Session.append` 同步清洗内存上下文,保留制表符、换行及其余 Unicode无 schema、migration 或存量数据改动。相关 6 项单元测试、Python 编译及 diff 格式检查通过;未设置 `ZCBOT_TEST_DB_URL`,未连接数据库。 - **07-31 / 0.60.17 / 消息 JSONB NUL 字符兼容**:外部工具从论文、PDF 等来源提取的文本可能夹带真实 NULPython JSON 会编码为 PostgreSQL `jsonb` 无法转换成 text 的 `\u0000`,导致 tool message INSERT 回滚并中断 run。新增递归清洗并在 `Message.payload` ORM 写入边界统一守门,`Session.append` 同步清洗内存上下文,保留制表符、换行及其余 Unicode无 schema、migration 或存量数据改动。相关 6 项单元测试、Python 编译及 diff 格式检查通过;未设置 `ZCBOT_TEST_DB_URL`,未连接数据库。
- **07-31 / 0.60.16 / platform 历史 task 稳定进入 + 新建任务名称可选**:普通 platform iframe 不再复用 localStorage 缓存 JWT 抢跑,始终等待父页面本次 `zcbot-token` 后再进入初始 task消除旧 token 401 后界面永久停在“加载中”的时序;企微/App fragment 登录路径不变。`POST /v1/tasks` 省略/留空 name 且提供 working_dir 时自动以“新对话”占位并启用首条消息标题生成,旧 `auto_title` 语义继续兼容;快速新对话不再发送冗余字段,自定义创建统一为工作目录必填、任务名选填,并换用可搜索/可创建的目录组合框。27 项无 DB 测试、Python 编译、3 个 JavaScript 语法及 diff 格式检查通过DB 路由用例已补,未配置 `ZCBOT_TEST_DB_URL` 时安全跳过。 - **07-31 / 0.60.16 / platform 历史 task 稳定进入 + 新建任务名称可选**:普通 platform iframe 不再复用 localStorage 缓存 JWT 抢跑,始终等待父页面本次 `zcbot-token` 后再进入初始 task消除旧 token 401 后界面永久停在“加载中”的时序;企微/App fragment 登录路径不变。`POST /v1/tasks` 省略/留空 name 且提供 working_dir 时自动以“新对话”占位并启用首条消息标题生成,旧 `auto_title` 语义继续兼容;快速新对话不再发送冗余字段,自定义创建统一为工作目录必填、任务名选填,并换用可搜索/可创建的目录组合框。27 项无 DB 测试、Python 编译、3 个 JavaScript 语法及 diff 格式检查通过DB 路由用例已补,未配置 `ZCBOT_TEST_DB_URL` 时安全跳过。

View File

@ -1,3 +1,3 @@
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。 # zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
# 改版本只动这一行。 # 改版本只动这一行。
__version__ = "0.60.18" __version__ = "0.60.19"

View File

@ -7,6 +7,7 @@ from __future__ import annotations
import asyncio import asyncio
import time import time
from typing import Any
from uuid import UUID from uuid import UUID
from fastapi import Depends, HTTPException from fastapi import Depends, HTTPException
@ -381,7 +382,7 @@ def register_message_routes(app, *, require_user) -> None:
from ..common import task_dict from ..common import task_dict
with session_scope() as s: with session_scope() as s:
row = s.execute( row = s.execute(
select(Task.run_status) select(Task.run_status, Task.title_source)
.where(Task.task_id == tid, Task.user_id == user_id) .where(Task.task_id == tid, Task.user_id == user_id)
.with_for_update() .with_for_update()
).first() ).first()