fix(backend): 收敛 LLM finish_reason 契约、修复 redacted_thinking 串写与 Windows 平台缺陷 - #158
Merged
Conversation
统一 finish_reason 口径: - 六值枚举 + raw 逃生舱,OpenAI / Anthropic 各一张映射表;适配器漏归一化时 __post_init__ 降级为 other 并打 warning - anthropic_client 的 stop_reason 改为 _finish_reason 状态机,修复 message_stop 硬编码 stop 覆盖 message_delta 已给出的 tool_use,导致工具执行后 ReAct 循环 直接终止 - codex/responses 修正 _saw_tool_call(Responses 在工具场景只报 response.completed),补 response.incomplete -> truncated 分支 - 只读批次加 return_exceptions=True 与 _finish_tool_execution_safe,避免单个 只读工具抛异常中断整批、留下未闭合的 tool_call 序列 修复 redacted_thinking 数据串写: - redacted 块的 data 原本被写进 reasoning_signature,造成两条真实失败路径: 仅含 redacted 的轮次里加密块被整体丢弃;同时含 thinking 与 redacted 的轮次里 data 覆盖真正的 signature_delta,发给 Claude 的是加密数据而非签名 - 新增 LlmDelta.reasoning_redacted_data 承载加密块, _build_anthropic_thinking_blocks 改为返回块列表让 redacted 独立成块, session_stream 四处回灌点与 reasoning 分支同级而非嵌套 测试: - 17 处夹具改用 FinishReason 合法值(护栏抓出假 client 喂的是 provider 原始值 "stop"/"length",被降级成 other 后令续写分支静默失效) - 新增 message IR 回归测试,覆盖 thinking 签名三态与只读批次异常序列闭合
路径持久化失真: - FileSnapshot.path 与竞赛 skill 的 created_files / created_dirs / project_dir 改用 as_posix()。这些值既进 API 响应又持久化到 file_snapshots.json,存平台 原生分隔符会导致 Windows 建的工作区在其他平台上 key 全不匹配、文件被误判为 已变更 SQLite 连接泄漏(Windows 上锁住 .db 文件,删除报 WinError 32): - with sqlite3.connect(...) 只管事务不管连接,退出 with 后连接仍打开;Linux 允许 unlink 已打开文件所以长期无感,Windows 会直接失败 - sqlite_graph_store 的 list 路径改显式 try/finally 关闭并补 commit - workspaces_resources_files 的 _create_graph_db_at_path / _write_knowledge_db_metadata、file_initializer 的 _write_knowledge_db_metadata / _create_graph_db_tables 四处改用 contextlib.closing(这四处原本就有显式 commit,异常路径未提交等价于回滚) - 删除知识图谱改为先释放缓存 service 再 unlink,并按规范走 as_system_path() 测试改为平台无关写法: - write_text 显式 newline="\n",避免 Windows 上被转成 CRLF - acp_command 硬编码 python3 改 sys.executable
This was referenced Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #156
Closes #157
改动概述
两个独立主题,各一个 commit,互不依赖。
1. 收敛 LLM finish_reason 契约并修复 redacted_thinking 数据串写(#156)
finish_reason 统一口径
raw逃生舱,OpenAI / Anthropic 各一张映射表__post_init__降级为other并打 warning,避免非法值静默穿透anthropic_client的stop_reason改为_finish_reason状态机,修复message_stop硬编码stop覆盖message_delta已给出的tool_use,导致工具执行后 ReAct 循环直接终止codex/responses修正_saw_tool_call(Responses 在工具场景只报response.completed),补response.incomplete→truncated分支return_exceptions=True,避免单个只读工具抛异常中断整批、留下未闭合的 tool_call 序列redacted_thinking 修复
redacted_thinking的data(加密推理内容)原本被写进reasoning_signature(可读 thinking 的签名),两条失败路径详见 #156。修复方式为新增独立字段reasoning_redacted_data,回灌函数改为返回块列表让 redacted 独立成块。2. 修复 Windows 上的路径失真与 SQLite 连接泄漏(#157)
FileSnapshot.path等改用as_posix():这些值既进 API 响应又持久化,存原生分隔符会导致 Windows 建的工作区在其他平台上 key 全不匹配with sqlite3.connect(...)改为显式关闭:该写法只管事务不管连接,Windows 上锁住 .db 文件导致删除报WinError 32newline="\n"、sys.executable验证
在 Windows(win32 / Python 3.12.11)本地跑通:
ruff format --check app/ruff check(改动文件)redacted_thinking 与 sqlite 泄漏两处修复均走真实链路验证,并用「临时回滚修复」做反证确认断言具备鉴别力,而非空转通过。
关于测试环境的说明
本仓
vendor/sqlite-vec/**/*.dll属 gitignored,干净 checkout 缺少该二进制时,test_sqlite_kb_service.py与test_global_workspace_file_routes.py共 12 例会失败。该现象与本 PR 无关(在不含本 PR 的upstream/dev上逐条重现),补齐二进制后全绿。这两个文件目前都在 CI 的--ignore列表内。顺带发现
ensure_vec_extension会把「扩展文件缺失」误报为「平台不支持」,已记录在 #157 末尾,未在本 PR 修改,避免扩大范围。审阅提示
workspaces_resources_files.py与 fix(web): 修复文件列表结束标记显示异常 #155 改动同文件,cherry-pick 时经 git 自动合并,已确认两边逻辑共存(本 PR 的closing+ fix(web): 修复文件列表结束标记显示异常 #155 的上传重命名)