Files
codex-app-server/docs/thread-resolve-fix.md
T
host 613ff4e7c4 fix: 线程解析按 home×provider 穷尽回退(共享 home + sub2api)
生产实测:app-server 按进程 provider 过滤 thread/list,
不带 sub2api 注入看不到 sub2api 下建的 thread;本地
worker 又用共享 home 而非租户 home。旧解析只查租户
home + 缺省 provider,本地任务一律 404。

修法(只改服务端,不动派发):_run_host_cli 支持顶层
--model-provider;_list_task_threads 按 home(租户→共享,
共享取 host-config-host.json 的 codex_home)× provider
(缺省→sub2api,仅配了 SUB2API_BASE_URL 时)穷尽,首个
非空即停;_resolve_task_thread 把 provider 带给后续的
thread-read/rename/archive CLI;_task_thread_read 改用
解析出的 home + provider(此前误用租户 home)。

三套件:cloud 957 OK(4 跳过)、host 91 OK、deploy 29 OK。
新测试 9 个。未动派发:本地改租户 home 会丢共享 home
里的 skills,另案处理。
2026-10-28 05:36:18 +08:00

64 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 线程解析修复:provider 过滤 + 共享 home 回退
## 故障(生产实测 2026-10-28)
本地任务的 thread rename/archive/unarchive 稳定 404
`thread not found`,thread/read 回 200 但 thread 为 null。
而同一任务的 worktree、bindings、快照、心跳、移交全部正常。
## 定位(证据链,全部在生产主机上实测)
1. host-state 里有该任务的 thread_id,cwd 与服务端推导的
worktree 路径一字不差;rollout 文件的 session_meta cwd
也是同一路径;state_5.sqlite 的 threads 表里有该行
(cwd 正确、archived=0、最新)。
2. 不带 provider 注入的 app-server 进程调 thread/list:
全量翻页(cursor 可用)共 77 条,探针 thread 不在其中;
带 cwd 过滤时回空;页内已知 thread 的 cwd 过滤正常回 1 条。
3. 区分点是 provider:列出的 77 条全是 xcmapi,探针两条
是 sub2api;带 `--model-provider sub2api` 注入的进程调
同一 cwd 过滤,立刻回 1 条(正是探针 thread),无过滤
首页即含它。
4. 第二个错位:服务端一直查租户 home
(tenants/<项目>/codex-home),本地 worker 按
host-config-host.json 用共享 home
(/var/lib/codex-app-server/codex-home),旧 thread 全在后者。
结论:app-server 按进程 provider 过滤 thread/list,且
服务端只查租户 home——两个错位叠加,本地任务解析必 404。
不是分页 cap(翻页后仍无)、不是 cwd 记错、不是 home 丢数据。
## 修法(只改服务端,不动派发)
`cloud/server.py`:
- `_run_host_cli` 新增 `model_provider` 参数,拼在子命令
之前(host.py 顶层参数,拼进 argv 会被子命令解析器拒绝)。
- `_list_task_threads` 按序穷尽,首个非空即停:
home:租户 home → 本地 worker 共享 home
(`_local_worker_codex_home`,只读 host-config-host.json
的 codex_home 一键,缺失/解析失败时跳过);
provider:缺省 → sub2api(仅当 server 进程配了
SUB2API_BASE_URL,否则 host.py loud fail,不能变 502)。
任一候选成功回空即停(空就是空);全部报错才 502 首错。
- `_resolve_task_thread` 返回 provider,后续的 thread-read /
rename / archive / unarchive 原样带 provider——同一 thread
在另一 provider 进程里同样看不到,丢了它改操作会 502。
- `_task_thread_read`(#103 的富化 read)此前解析后又用
租户 home 调 thread-read,已改成解析出的 home + provider。
不改派发的原因:本地 worker 改租户 home 会丢共享 home
里的 skills 等内容,有回归风险;且服务端兜底已覆盖全部
现存 thread。租户隔离(本地任务共用一个 home)是另案,
不在本批修。
## 未覆盖
- Docker 任务仍 409(thread 在容器内,服务端查不到是设计)。
- `_task_threads` 列表端点同样走 `_list_task_threads`,兜底
对它同样生效;但它不翻页,只返回解析到的该任务 thread。
- 真 PR 创建仍未实弹(与本批无关)。
- 新测试 9 个:`cloud/tests/test_thread_resolve.py`
(CLI 参数位置、共享 home 读取、回退顺序、空→404、
host.py 失败→502)。