Files
codex-market-app/C:\Users\mac\.claude\projects\C--Users-mac-Documents------ProjectDown-codex-market-app\memory\codex-model-catalog-history-loss.md
T

22 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.
---
name: codex-model-catalog-history-loss
description: 「Codex切模型后会话记录消失」的真因——config指向的model不在模型目录→Codex以未知模型启动、侧栏历史还原失败。排查此类"记录丢失"必读
metadata:
type: project
---
客户报「Codex 切模型后会话记录莫名丢失」。真因不是数据丢失,是**显示丢失**:`~/.codex/config.toml` 的根级 `model` 指向了一个**不在模型目录 `cc-switch-model-catalog.json` 里的 slug** → Codex 本体以未知模型启动,无法解析该模型 → 侧栏历史线程还原失败,看起来"会话没了"。rollout 文件、`state_*.sqlite`(threads)、`session_index.jsonl` 全部无损,切回一个目录内已有的模型(或把该 model 登记进目录)后重启 Codex 即恢复。
**触发的代码 bug(electron/lib/router.js,已修)**:`applyModelCatalog(group)` 旧代码首行 `if (!group.contextWindow) return` + `if(!win) return`,即分组没填「上下文窗口」就跳过目录登记;而 `setConfigModel(model)` 却无条件把 `model=` 写进 config.toml → **非对称**:config 指向的模型没进目录。分组的 contextWindow 除 DeepSeek 外普遍为空,所以切到目录里没有的模型必现。
**修复**:① `applyModelCatalog` 去掉 contextWindow 前置条件,只要有 model 就登记(visibility=list,窗口回退 输入→模板默认→128000);② 新增 `ensureModelInCatalog()` 内嵌进 `setConfigModel`,写 config 前保证该 slug 在目录里 = 不变量「config 指向的 model 必在目录」,任何切换路径+历史残骸环境都自愈。③ **关键补强**:用户是在 Codex 本体的模型选择器里切模型的,那条路径**不经过本 App**,只登记单个 model 不够——切到别的同代模型(如 tokendun 有 gpt-5.6-luna/sol/terra 三个)又会丢。故新增 `syncCatalogFromProvider(group)`:拉分组 `/v1/models`(复用 `fetchModels`),把全部**文本**模型(排除 image/imagine/whisper/audio/tts/embed/rerank/review 等非对话模型,正则 NON_TEXT_MODEL_RE)一次性登记进目录。在 `applyDirectToCodex` / `applyToCodex`(fire-and-forget) 及 **main.js 应用启动时**(`router.llmGroup()` 取当前激活分组) 各触发一次 → 既有安装无需重存分组即自动修复。
**已发布**:热更 v1.5.20(mandatory=true, min 1.5.0)已上 gitea hot 通道。升级后**仍需用户手动重启 Codex 本体**(App 修好目录,Codex 下次启动才读)。发布见 [[release-publish-flow]]。
**诊断手法(会话本文不用读,只看分布)**:
- `sqlite3 state_*.sqlite "SELECT model_provider,model,COUNT(*) FROM threads GROUP BY 1,2"` → 全 null/同值说明侧栏不是按 model/provider 过滤,排除 provider-sync 方向。
- node 读 catalog 打印各 `slug|visibility|context_window`,比对 config.toml 的 `model=` 是否在其中 —— 不在即命中本 bug。
- `session_index.jsonl.bak-*` 若有多份,是用户反复跑 provider-sync 抢救历史的痕迹。
单机即时抢救:把 config 当前 model 用模板克隆登记进 catalog(写 .bak-fix 备份),重启 Codex 即回。相关:[[router-dual-platform-config]] [[router-dual-active-slots]] [[release-publish-flow]]。