From c89ba45f7fa62270477fe5b0df560b07decb57ad Mon Sep 17 00:00:00 2001 From: Willem Jiang Date: Mon, 28 Sep 2026 11:49:20 +0800 Subject: [PATCH] chore(doc):fix the changelog section error (#5868) --- CHANGELOG.md | 89 +++++++++++++------------------------------------ CHANGELOG_zh.md | 59 ++++++++++---------------------- 2 files changed, 41 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ace041f33a..e96115cac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1358,6 +1358,30 @@ This release closes that milestone with **181 merged pull requests**. some later edit. The loader now reads once through a shared `file_signature.read_config_with_signature()` helper that signs exactly the returned bytes; a racing edit can only cost one extra reload. ([#5848]) +- **dev:** `make stop` / `make dev` can now reclaim dev ports held by a sibling + worktree whose path contains spaces. `serve.sh` built its worktree-root list + with `awk '{print $2}'` over `git worktree list --porcelain`, whose paths are + unquoted, so `.../deer flow two` was recorded as `.../deer`; a Gateway or + frontend started from that worktree was never recognised as deer-flow's and + the start aborted with "port already in use". The whole path is kept now. ([#5856]) +- **uploads:** A malformed `files[*].size` in a run's message metadata no + longer fails the whole run. `UploadsMiddleware` validated every other field + of a client-supplied file entry fail-soft but passed `size` straight to + `int()`, so a value such as `"abc"` or a list raised out of `before_agent` + before the model was called — and again on every edit or regenerate of that + message, since the entry is carried over verbatim. The size only feeds the + human-readable line in ``; unusable values now fall back to + `0`, the same as a missing size, while numeric strings keep working. ([#5855]) +- **release:** Bumping the version no longer leaves `backend/uv.lock` behind. + `scripts/bump_version.sh` rewrote `backend/pyproject.toml`, `frontend/package.json` + and the Helm chart, but the lockfile records the root package's own version too + (uv keeps its PEP 440 form, so `2.1.0-rc0` is stored as `2.1.0rc0`). The + documented release step therefore produced a commit whose lock CI rejects: + `uv lock --check` fails on the stale lock and `uv sync --locked` refuses the + tree, and with pre-commit installed it broke a step earlier on the + `uv-lock-check` hook. The script now refreshes the lock with `uv lock` and exits + before editing anything when `uv` is missing, instead of leaving a half-bumped + working tree behind. Only the root package's version line moves. ([#5859]) ### Security @@ -2519,71 +2543,6 @@ This release closes that milestone with **772 merged pull requests**. ### Fixed -- **dev:** `make stop` / `make dev` can now reclaim dev ports held by a sibling - worktree whose path contains spaces. `serve.sh` built its worktree-root list - with `awk '{print $2}'` over `git worktree list --porcelain`, whose paths are - unquoted, so `.../deer flow two` was recorded as `.../deer`; a Gateway or - frontend started from that worktree was never recognised as deer-flow's and - the start aborted with "port already in use". The whole path is kept now. ([#5856]) -- **uploads:** A malformed `files[*].size` in a run's message metadata no - longer fails the whole run. `UploadsMiddleware` validated every other field - of a client-supplied file entry fail-soft but passed `size` straight to - `int()`, so a value such as `"abc"` or a list raised out of `before_agent` - before the model was called — and again on every edit or regenerate of that - message, since the entry is carried over verbatim. The size only feeds the - human-readable line in ``; unusable values now fall back to - `0`, the same as a missing size, while numeric strings keep working. ([#5855]) -- **release:** Bumping the version no longer leaves `backend/uv.lock` behind. - `scripts/bump_version.sh` rewrote `backend/pyproject.toml`, `frontend/package.json` - and the Helm chart, but the lockfile records the root package's own version too - (uv keeps its PEP 440 form, so `2.1.0-rc0` is stored as `2.1.0rc0`). The - documented release step therefore produced a commit whose lock CI rejects: - `uv lock --check` fails on the stale lock and `uv sync --locked` refuses the - tree, and with pre-commit installed it broke a step earlier on the - `uv-lock-check` hook. The script now refreshes the lock with `uv lock` and exits - before editing anything when `uv` is missing, instead of leaving a half-bumped - working tree behind. Only the root package's version line moves. ([#5859]) -- **config:** A `config.yaml` edit that lands while the previous edit is still - being loaded is no longer lost until the next edit. `get_app_config()`'s - loader parsed the file and then hashed it again to record the cache - signature, so a write between those two reads left the cache holding the - older content under the newer content's signature — a state the signature - comparison can never detect. The loader now reads the file once and signs - the bytes it parsed; a write that races the load just triggers one more - reload on the next call. ([#5848]) -- **config:** `request_admission.requests_per_minute` and `max_queue_size` now - accept `$VAR` environment references like every other field. Both are strict - integers so a bool or float is still rejected, but `$VAR` substitution always - produces a string, so `requests_per_minute: $RPM` failed the whole config load - with "Input should be a valid integer" even when `RPM=60`. A decimal literal - delivered as a string is now converted before the strict check; any other - string is still rejected. ([#5838]) -- **scheduler:** Pausing a scheduled task no longer loses the pause when a - dispatch is in flight on SQLite. `release_dispatch_lease` guards on the lease - owner — which pausing clears — but read the row without taking SQLite's - writer, so a stale read passed the guard and wrote the task back to - `enabled` with `next_run_at` untouched, leaving the scheduler firing a task - the API had reported as paused. The read now takes the writer first, as every - other mutating path in that repository does. PostgreSQL was unaffected. - ([#5777]) -- **mcp:** Lazy MCP initialization no longer runs tool discovery twice when - discovery itself raises a `RuntimeError` such as `McpTaskConfigurationError`. - The `asyncio.run` fallback in `get_cached_mcp_tools()` was meant only for - `get_event_loop()` failing, but it also caught discovery errors and - re-spawned every stdio server (and re-fetched OAuth tokens) before giving - up; inside a running loop it also logged a misleading "asyncio.run() cannot - be called from a running event loop" traceback instead of the real cause. -- **uploads:** Deleting an uploaded document no longer deletes the converted - Markdown beside it. Conversion names a companion after the document's stem - and falls back to a `_N` suffix when that name is taken, so the `.md` next to - a document can belong to another document sharing the stem, or to the user: - uploading `a.docx` and `a.pdf` produced `a.md` and `a_1.md`, and deleting - `a.pdf` destroyed `a.docx`'s companion. Companions now survive their - document, stay listed, and can be deleted on their own. ([#5673]) -- **subagents:** Recognize zero-byte regular deliverables in remote sandbox - acceptance checks. Readable empty files now satisfy `exists` and - `file_written` and deterministically fail `non-empty`, instead of remaining - UNVERIFIED. ([#5559]) - **frontend:** Keep the `…` (kebab) menu on project chat rows inside the sidebar. In the sidebar's grouped Projects mode the indented nested menus kept `SidebarMenu`'s `w-full` while carrying an extra `ml-4`, so they were diff --git a/CHANGELOG_zh.md b/CHANGELOG_zh.md index b95f7c7440..88e0697bd5 100644 --- a/CHANGELOG_zh.md +++ b/CHANGELOG_zh.md @@ -393,6 +393,23 @@ `custom/` 下的一级链接,但 `delete_custom_skill` 用 `shutil.rmtree` 删除包目录,而它拒绝 符号链接:删除在写入历史记录之后以 `OSError` 失败,退出时清空了用户的技能投影视图, `DELETE /api/skills/custom/{name}` 返回 500。现在只移除链接本身,绝不触碰其指向的外部目录。([#5881]) +- **开发:** 当同级 worktree 的路径包含空格时,`make stop` / `make dev` 现在也能回收它占用的 + 开发端口。`serve.sh` 用 `awk '{print $2}'` 解析 `git worktree list --porcelain` 来构建 + worktree 根目录列表,而该输出中的路径不加引号,因此 `.../deer flow two` 被记录成了 + `.../deer`;从那个 worktree 启动的 Gateway 或前端永远不会被识别为 deer-flow 的进程, + 启动会以“端口已被占用”中止。现在会保留整条路径。([#5856]) +- **上传:** 运行消息元数据中格式错误的 `files[*].size` 不再导致整个运行失败。 + `UploadsMiddleware` 对客户端提供的文件条目的其他字段都做了容错校验,唯独把 `size` 直接交给 + `int()`,因此 `"abc"` 或列表这样的值会在调用模型之前从 `before_agent` 抛出——而且由于该条目 + 会被原样带入,之后每次编辑或重新生成这条消息都会再次失败。该字段只用于 `` + 里的可读大小;现在无法使用的值会回退为 `0`,与缺失时一致,数字字符串仍然有效。([#5855]) +- **发布:** 版本升级不再把 `backend/uv.lock` 落下。`scripts/bump_version.sh` 会改写 + `backend/pyproject.toml`、`frontend/package.json` 与 Helm chart,但 lockfile 同样记录了 + 根包自身的版本(uv 保留其 PEP 440 形式,因此 `2.1.0-rc0` 存为 `2.1.0rc0`),于是文档给出的 + 发布步骤产出的提交会被 lock 相关 CI 拦下:`uv lock --check` 判其过期,`uv sync --locked` + 也会拒绝该工作区;装了 pre-commit 时还会更早在 `uv-lock-check` 钩子上失败。现在该脚本会用 + `uv lock` 刷新 lockfile,并在缺少 `uv` 时于修改任何文件之前退出,而不是留下一个只改一半的 + 工作区。实际改动仅涉及根包的那一行版本号。([#5859]) - **前端:** 子任务渲染状态不再在 `MessageList` 渲染过程中被就地修 改。子任务同步从渲染阶段移入 effect,因此即使任务上下文尚未发布 更新,卡片也能立即拿到纯派生自消息的快照——修复了最终流式参数与 @@ -2193,48 +2210,6 @@ ### 修复 -- **开发:** 当同级 worktree 的路径包含空格时,`make stop` / `make dev` 现在也能回收它占用的 - 开发端口。`serve.sh` 用 `awk '{print $2}'` 解析 `git worktree list --porcelain` 来构建 - worktree 根目录列表,而该输出中的路径不加引号,因此 `.../deer flow two` 被记录成了 - `.../deer`;从那个 worktree 启动的 Gateway 或前端永远不会被识别为 deer-flow 的进程, - 启动会以“端口已被占用”中止。现在会保留整条路径。([#5856]) -- **上传:** 运行消息元数据中格式错误的 `files[*].size` 不再导致整个运行失败。 - `UploadsMiddleware` 对客户端提供的文件条目的其他字段都做了容错校验,唯独把 `size` 直接交给 - `int()`,因此 `"abc"` 或列表这样的值会在调用模型之前从 `before_agent` 抛出——而且由于该条目 - 会被原样带入,之后每次编辑或重新生成这条消息都会再次失败。该字段只用于 `` - 里的可读大小;现在无法使用的值会回退为 `0`,与缺失时一致,数字字符串仍然有效。([#5855]) -- **发布:** 版本升级不再把 `backend/uv.lock` 落下。`scripts/bump_version.sh` 会改写 - `backend/pyproject.toml`、`frontend/package.json` 与 Helm chart,但 lockfile 同样记录了 - 根包自身的版本(uv 保留其 PEP 440 形式,因此 `2.1.0-rc0` 存为 `2.1.0rc0`),于是文档给出的 - 发布步骤产出的提交会被 lock 相关 CI 拦下:`uv lock --check` 判其过期,`uv sync --locked` - 也会拒绝该工作区;装了 pre-commit 时还会更早在 `uv-lock-check` 钩子上失败。现在该脚本会用 - `uv lock` 刷新 lockfile,并在缺少 `uv` 时于修改任何文件之前退出,而不是留下一个只改一半的 - 工作区。实际改动仅涉及根包的那一行版本号。([#5859]) -- **配置:** 在上一次编辑仍在加载时落盘的 `config.yaml` 编辑,不再要等到下一次编辑才生效。 - `get_app_config()` 的加载器先解析文件,再重新读取一遍来计算缓存签名,因此夹在两次读取 - 之间的写入会让缓存以较新内容的签名保存较旧的内容,而签名比较永远无法发现这种状态。 - 现在加载器只读取文件一次,并对解析的那份字节计算签名;与加载竞争的写入只会在下一次 - 调用时多触发一次重载。([#5848]) -- **配置:** `request_admission.requests_per_minute` 与 `max_queue_size` 现在与其他字段一样 - 接受 `$VAR` 环境变量引用。这两个字段是严格整数,布尔值与浮点数仍会被拒绝;但 `$VAR` - 替换得到的永远是字符串,因此即使 `RPM=60`,`requests_per_minute: $RPM` 也会让整个配置 - 加载失败并报 "Input should be a valid integer"。现在以字符串形式到达的十进制整数字面量会在 - 严格校验之前被转换;其他字符串仍会被拒绝。([#5838]) -- **调度器:** 在 SQLite 上,调度分发进行中暂停计划任务时不再丢失暂停状态。 - `release_dispatch_lease` 依据租约持有者做校验(暂停会清除该字段),但读取任务行时没有先获取 - SQLite 的写锁,因此过期的读取会通过校验,并把任务状态写回 `enabled` 且不改动 `next_run_at`, - 导致接口已回复“已暂停”的任务仍被继续触发。现在该读取会像该仓储中其他写入路径一样先获取写锁。 - PostgreSQL 不受影响。([#5777]) -- **mcp:** MCP 延迟初始化在工具发现本身抛出 `RuntimeError`(例如 - `McpTaskConfigurationError`)时,不再把发现流程跑两遍。`get_cached_mcp_tools()` 里的 - `asyncio.run` 兜底只为 `get_event_loop()` 失败而设,却同时捕获了发现阶段的错误,于是在 - 放弃之前会重新拉起每一个 stdio 服务器(并重新获取 OAuth 令牌);在运行中的事件循环里, - 它记录的还是误导性的 "asyncio.run() cannot be called from a running event loop" - 堆栈,而不是真正的原因。 -- **上传:** 删除已上传的文档时,不再连带删除其旁边转换生成的 Markdown。转换以文档主干名 - 命名配套文件,名称被占用时回退为 `_N` 后缀,因此文档旁的 `.md` 可能属于主干名相同的另一个 - 文档,或属于用户自己:上传 `a.docx` 与 `a.pdf` 会生成 `a.md` 与 `a_1.md`,删除 `a.pdf` - 却会销毁 `a.docx` 的配套文件。现在配套文件会保留、继续出现在列表中,可单独删除。([#5673]) - **nginx:** 把 600 秒读取超时扩展到其余两个会等待 Gateway 的 location,它们在线程路由的修复 之后仍沿用 nginx 默认的 60 秒。`/api/` 兜底 location 之后:无状态的 `POST /api/runs/wait` 阻塞在同一套运行完成等待上,并在客户端断开时取消该运行,因此等待超过 60 秒的 API 调用方会