菜单

波波
发布于 2026-06-07 / 4 阅读
0

Codex Desktop 切换 API 后会话“丢失”修复

最近在使用 Codex Desktop 时遇到一个问题:切换 API/provider 之后,重启 App,左侧历史会话几乎都不见了,只剩下最近几条记录。第一眼看上去像是会话被删了,但实际排查下来,这不是数据丢失,而是旧会话被 App 的可见性逻辑过滤掉了。

问题出现后,我先检查了本地 Codex 数据目录。Codex 的会话数据主要分布在几个地方:

~/.codex/state_5.sqlite

~/.codex/session_index.jsonl

~/.codex/sessions/**/*.jsonl

~/.codex/.codex-global-state.json

最开始只修复 session_index.jsonl 并没有解决问题。进一步检查发现,SQLite 数据库和索引里其实都有完整记录:数据库里有 255 条 thread,索引里也有 255 条,但 Codex Desktop 的线程列表接口只显示了几条。这说明问题不在“数据不存在”,而在“App 没把它们展示出来”。

真正的关键线索来自 rollout 日志,也就是 ~/.codex/sessions/.../rollout-xxx.jsonl。这些旧会话的第一行通常是 session_meta,里面保存了会话元数据,例如:

{
 "type": "session_meta",

  "payload": {

    "thread_source": "user",

    "model_provider": "custom"

  }

}

部分旧会话的 model_provider 是之前自定义 API/provider 写入的值,例如 customflashrain。实验发现,只把某个旧会话 rollout 第一行里的 model_provider 改成 Codex Desktop 当前能识别的 provider,比如 ai,这个会话就能重新出现在列表里。

也就是说,根因是:

Codex Desktop 在重建或过滤会话列表时,不只看 SQLite 和 session_index.jsonl,还会参考 rollout 日志里的 session_meta.payload.model_provider。当这个 provider 是当前版本不认识的旧值时,会话并没有被删除,但会被 UI 过滤掉,看起来就像“历史会话丢失”。

最终修复策略是:

1. 备份 state_5.sqlite、session_index.jsonl、global state 和被修改的 rollout 文件

2. 只处理顶层用户会话,不处理 subagent 会话

3. 将旧 provider 值归一化为 ai

4. 同步修复 SQLite threads.model_provider

5. 同步修复 rollout 第一行 session_meta.payload.model_provider

6. 重建 session_index.jsonl

7. 展开侧边栏 chats/threads 区域

8. 对 SQLite 做 WAL checkpoint,确保修改落盘

9. 完全退出 Codex Desktop 后重新打开

修复后重新检查:

DB 会话数:255
索引会话数:255
缺失会话:0
旧 provider 残留:0

Codex Desktop 侧也重新能看到旧会话了。部分很旧的会话在搜索里可能仍不命中,但通过 thread id 可以读到,说明数据本身已经恢复,剩下更多是 App 搜索缓存或加载策略的问题。

这次排查最大的经验是:不要把“UI 看不到”直接等同于“数据丢失”。尤其是桌面端应用,经常会有多份状态源:数据库、索引文件、日志文件、UI 持久化状态。只修其中一个地方,很可能会被另一个状态源重新覆盖。

后续如果再次切换 API/provider,只要本地 ~/.codex/sessionsstate_5.sqlite 还在,会话大概率不会真的丢。即使左侧又看不到,也可以通过同样的思路恢复:先备份,再检查 provider 元数据,再重建索引。