Conversation
后缀适配(P1): - 前端新增 suffixWindowTokens/modelSlugFromRowName/suffixWindowString, 三处 parseModelMetadataDocument 调用点先剥 [1M] 后缀再解析导入文档 - 后端 parse_model_suffix 用 let-chains 折叠嵌套,窗口映射 1M=1e6/256K=256000 元数据健壮性(P2/P3): - 查询链 fallback 不再写死 gpt-5.5/272000:新增 fallback_template_info() 从 bundled 模板实时取;前端 metadataSourceTags/importPanelControls 接 fallbackSlug 字段 - vendor JSON 重复解析加 OnceLock 索引缓存(find_catalog_entry 热路径) - 新增 find_catalog_entry_for_test 钩子 + 2 个测试:精确匹配优先于大小写 变体、运行时缓存层大小写不敏感命中 - kimi-k2.8-preview 资产修正:max_output_tokens 131072、priority 9、补 base_instructions - 测试锁 SerializeCodexHomeTests::lock() 重构为 poison-tolerant,清除 22 处双重锁 - e2e_codex_real_cli 模型计数改为动态断言,codex 二进制缺失时 panic 带指引 - i18n:回退/匹配徽标文案全部走 tf() 模板,删除失效的 EN_PLAIN 硬编码 工程卫生: - 删除入库的浏览器自动化调试脚本,.gitignore 补 .zcode/ 等工作区产物规则 - clippy/fmt 对 PR 触及文件清零 验证:model_suffix 29/29、relay_config 163/163、lib 436/436、 前端 node --test 36/36、tsc --noEmit 通过
- importSaveDecision 对 documentBlank+imported 与 matchesBuiltin 两种情况 都返回「保存此模型」,语义统一为「保存成内置态」 - 面板按钮组从按状态显隐改为四按钮恒定渲染 + 置灰(importPanelControls) - runtime cache 测试 slug 改用 runtime-only-model,避开供应商资产新增条目
- builtinEntryToImportDocument 接受行名参数:预填文档的 slug 用用户 输入拼写(剥掉 [1M] 后缀),不再显示资产里的小写规范名 - 来源徽标从 i18n key + 参数改回纯文本下发(文案在 helper 内维护), 保存按钮文案统一为「保存此模型」,效果说明放 tooltip - importPanelControls 的 fallback 默认值改为 gpt-5.5,不再依赖调用方传 - 补回 main 上 customHeaders 功能块缺失(c00177e 整文件覆盖造成回退)
cherry-pick 冲突解决时误删了 Tauri 命令注册对应的函数体,从 main 恢复
对照用户认可的旧分支设计(3de63f4/c00177e)还原: 1. 来源徽标(标签):补回 .relay-model-source-badge 胶囊样式及 builtin(绿)/custom(主色)/fallback(中性)三色变体,共 83 行 CSS。cherry-pick 时整文件覆盖丢了这段样式,导致面板里只有 裸文字没有标签胶囊。 2. workbench 顶部状态行:移除 .relay-model-import-status 渲染。 徽标已承载「当前用什么元数据」的信息,顶部一行说明文字属于 早期过渡设计,用户确认不要。 3. 导入按钮颜色:恢复 className 三元表达式 (imported → relay-model-import-custom、命中内置 → relay-model-import-builtin),variant 恒为 ghost。 c8ed14b 重构时误把颜色 class 丢成纯 relay-model-import-button。 验证:tsc 通过、37 个前端测试全过;CDP 冒烟确认 28 个模型行 中命中内置的按钮带绿色边 class、面板内徽标渲染 「匹配:gpt-5.6 兼容」、状态行不再出现。
用户反馈保存键被置灰、清除逻辑不对——上一轮还原旧分支 UI 时把 按钮语义也带回了实验版(needsSave=false 时保存置灰、清除停在 空文档状态),偏离了 main 上日常使用的交互。 对齐 main 语义: 1. 保存键:disabled 只取决于 JSON 解析是否成功(!parseOk), 不再因「内容与内置一致、无自定义可写」而置灰。内容==内置时 点保存 = 确认使用内置并关闭面板(applyModelMetadataImport 原有的 needsSave 短路逻辑不变,不写自定义)。 2. 清除键:摘除该模型自定义配置后直接关闭面板(保留上下文 窗口列),与 main 的「清除导入配置」一步到位一致;不再停在 「文档已清空、保存键置灰」的死胡同。title 同步更新。 3. importSaveDecision 的「内置一致且无自定义」分支 title 改为 「内容与内置元数据一致,保存后继续使用内置元数据」,与可点 的按钮状态一致。 CDP 实测:面板打开保存键即可点;改 display_name 保存为自定义 后按钮变「更新此模型配置」;点清除后面板关闭、自定义被摘除、 行图标恢复 builtin 绿边。37 个前端测试全过,tsc 无错误。
- 三枚状态徽标(匹配来源/回退模板/自定义)配合恒定四按钮与动态保存文案,元数据匹配现状一目了然 - 清除=只清空面板草稿(面板保持打开、不摘配置);保存=唯一写入点;与内置全字段一致不写自定义,部分编辑(含仅改窗口/压缩)如实落自定义 - 导入草稿身份只用行索引,元数据键按行解析(改名未提交不再失明);[1M] 行现有配置文档可正常解析 - 内置命中即回填空窗口/压缩列(上游获取/手动提交/打开面板三入口共用裁决;后缀与已填值不覆盖) - 内置元数据索引透传 auto_compact_token_limit;e2e 断言随口径同步
.zcode/ 已在 .gitignore 声明不入库,此前误跟踪的两个 CDP 调试脚本与 .zcodeignore 一并从仓库移除(本地文件保留);.zcodeignore 补充进忽略列表防止再次混入。
cherry-pick 整文件覆盖 i18n-en.ts 后手工恢复时漏了 8 个仍有调用点的 EN_PLAIN 条目,英文界面下这 9 处调用点直接露中文。恢复其中 7 个 (热重载脚本、应用本地脚本及开关…、自定义请求头、请求头名称、 请求头值、自定义请求头会同时用于…、Host、Content-Length…); 「关闭官方低额度提示」的 hint 改用字典里已有的新文案 「关闭后仍可从 Codex 左下角账户菜单查看官方剩余额度。」,旧 key 随之废弃。3 个已无调用点的 key(部分脚本执行失败…等)确认删除。 i18n-verify 手动复核:8 个 MISSING 全部消失。
状态行(importPanelControls.status / importPanelStatus / ImportPanelStatus) 在 baed244 移除 JSX 渲染后已无任何消费点,但构建逻辑、CSS(.relay-model- import-status 三色与 .relay-model-metadata-tags 系列)和 10 条测试断言 仍在锁一份不存在的 UI;importPanelControls 的 matchedSource/fallbackSlug 参数随之失去消费点一并移除。另删 styles.css 中与上文完全重复的 .relay-model-metadata-import-warning 块。
1. MetadataSourceTag 删 text/title 渲染文案、改发结构化 source:
localizeMetadataSourceTag 不再用 slice("匹配:") 前缀切片和
全角括号正则从渲染文本反解参数——来源名含全角括号时正则会抓错
分组或静默降级,文案一改前缀切片就错位。fallbackSlug 空串兜底
到 bundled 首条,避免渲染「回退:」空后缀。
2. 跟随改名的 useEffect:cancelled 检查提前到 await 之后第一行
(try/catch 两分支,setBuiltinQueryState/setMetadataImportError
一并纳入),旧查询的迟到 error 不再把当前正确匹配误藏成回退态。
3. beginModelMetadataImport/rematchBuiltinImport 引入请求代数 ref:
命令式调用没有 effect cleanup 的 cancelled 通道,响应返回时代数
不匹配即整体丢弃——修掉「取消面板后被迟到响应重新打开」(面板
会带回陈旧文档)与「连点重新匹配互相覆盖」;关面板时代数自增,
作废所有在飞查询。
4. queryBuiltinCommand 失败从静默吞改为 console.warn:索引失败是
假阴性(行级标记/便利回填失效、不产错误数据),可诊断即可。
parse_model_metadata_map 现在把 key 统一剥 [1M] 后缀并做 ASCII 小写 归一、变体去重(后写者胜),与前端 canonicalizeModelMetadataMap 完全 一致;model_metadata_override_for_slug 相应从 find_map 首位命中简化为 归一 key 直接查表。 此前两侧消歧规则相反(前端末位胜 / Rust 首位胜,serde_json preserve_order 下按 JSON 文本序),旧数据同时存在 "DeepSeek-V4-Pro" 与 "deepseek-v4-pro[512K]" 时,前端显示的覆盖 与生成 catalog 实际生效的覆盖不是同一份。仅旧数据触发:新写入链路 两侧都已归一。 新增 metadata_map_normalizes_keys_with_last_write_wins 锁归一化与 后写者胜语义;既有两个 overlay 测试改为经 parse_model_metadata_map 构造(与生产链路同管道)。
1. 补回被 02ee176 无意删除的 gpt6_sol_luna_metadata_matches_official_efforts_fast_and_default_window (当时 commit message 未说明删除原因;资产与解析链路均未变化, 断言原样保留),并持 RUNTIME_CACHE_ENV_LOCK——catalog 生成链现在 会读 CODEX_HOME/models_cache.json。 2. builtin_model_metadata_matches_with_source / builtin_resolution_and_catalog_requirement_share_suffix_and_case_rules / builtin_model_metadata_index_covers_all_embedded_entries 三个测试 补同一把锁:它们直接调 builtin_model_metadata/builtin_model_metadata_index, 在装有真实 ~/.codex/models_cache.json 的机器上与临时改写 CODEX_HOME 的并行测试互踩进程级环境变量。 3. 新增 collect_entries_prefers_inline_suffix_over_model_windows_map: 锁定「行内 [1M] 后缀优先于 model_windows map」的语义(collect_catalog_entries 本 PR 起先取行内后缀、再回落 map)。
.zcode/ 拦不住工作区实际出现的 apps/codex-plus-manager/.zcodetmp/ (前缀不同且不在 .zcode/ 之下)。
上一轮 run 36219041571 的 macOS DMG (x64) 在 DMG 已成功创建后 detach /dev/disk2 失败(重试循环含 force 卸载跑了约 29 秒仍未成功), 属 Intel runner 的 mds/Finder 占卷偶发问题:本轮 commit 未触碰 scripts/installer/macos/package-dmg.sh,上一轮同 job 为绿。 无上游 rerun 权限,推空 commit 触发全新 run。
This branch has not been deployed
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.
一句话总结
这个 PR 把「模型元数据」从生成链里的隐形配置,变成管理器界面上一套看得见、读得懂、改得动的标签系统:模型处于什么状态、生成时会发生什么、还能做什么修改,全部直接写在用户眼前。
之前的问题
模型的元数据来自三层查找(精调/供应商兼容层 → 官方运行时缓存 → bundled 静态资产),状态组合很复杂,但界面上完全不可见:
[1M]后缀在界面、元数据键、生成链三处语义不一致(模型元数据严重缺失:主流第三方模型全部回落 gpt-5.5 兜底模板,建议内置供应商元数据 #2279),同一个模型换种写法结果就不同。结果就是:用户对元数据「不敢改、不会改、改了也不知道生效没有」。
之后:三枚标签,把全部状态空间摊开
每个模型的导入面板渲染三枚正交的状态徽标(横向排列、窄屏自动折行),简洁易懂地覆盖所有可能状态:
徽标以结构化
source字段下发(不再把渲染文案当数据传),调用方 localize 时统一走t()/tf()拼装。未命中内置 + 已有自定义时只显示 [自定义](自定义已覆盖,「回退」不再是当前事实,避免误导)。徽标之外是恒定渲染的四个操作(重新匹配 / 清除 / 取消 / 保存):按钮永远在同一位置,只用置灰表达可用性,不再出现「点一个键少一个键」;保存按钮的文案与 hover 说明随内容变化(「保存为自定义配置」「保存后恢复内置」……),按钮承诺与执行动作严格一致——任何时刻都能回答三个问题:现在用的是什么?保存会发生什么?还能做什么?
更自由的修改,且每一修改都安全
标签让状态可见,语义重构让修改无顾虑:
[1M]后缀 + 大小写不敏感),改名未提交时按行解析配置落点,清除/保存不再失明;历史数据里同名变体(如DeepSeek-V4-Pro与deepseek-v4-pro[512K])两侧统一按「后写者胜」归并,界面显示与生成 catalog 不再各选一份。内置命中,行列立即同步
上游获取、手动提交行名、打开导入面板三个入口共用一条回填裁决:内置命中且列为空时,立即回填上下文窗口(内置
context_window)与自动压缩(Codex++ 默认 90%;厂商条目若提供auto_compact_token_limit则优先换算)。[1M]后缀与用户已填值是显式意图,任何回填/导入都不得覆盖——所见即生成所得。支撑标签系统的底层重构
标签能被信任,前提是它与生成行为严格同源:
resolve_builtin_metadata单一解析器,生成链、UI 查询、判定、索引四个入口全部收敛到同一条三层查找链,UI 展示与生成的 catalog 不再可能分叉;[1M]后缀全链路一致(模型元数据严重缺失:主流第三方模型全部回落 gpt-5.5 兜底模板,建议内置供应商元数据 #2279):后缀窗口在生成链、导入面板、实时同步、元数据键归一中语义统一,后缀作为用户显式意图拥有最高优先级(行内后缀优先于model_windowsmap,有测试锁定);unsafe裸指针生命周期缓存,改为按路径 + (mtime, 长度) 指纹的运行时缓存;索引不再对每个 slug 重复读盘;内置查询区分「命中 / 未命中 / IPC 失败」三态,索引查询失败可诊断(console.warn),不再静默吞掉;builtin_model_metadata_index透传auto_compact_token_limit;资产元数据更新(12 个 assets/*.json)
gpt-5.3-codex-spark、deepseek-v4-flash-0731、deepseek-v4-pro-0813、deepseek-v4-flash-vision、glm-5v-turbo、kimi-k2.7-code-highspeed、MiniMax-M2.7-highspeed;doubao-seed-2.1-pro与qwen3-coder-plus上下文 256K→1M(会改变这两款的 auto compact 阈值);kimi-k3、kimi-k2.8-preview、mimo-v2.5的 max_output_tokens 修正为 131072;kimi-k2.8-previewpriority 7→9 并补base_instructions;gemini-3.8/3.7-flash、gemini-3.5-flash-lite、step-5-preview 补max_output_tokens: 65536;审计修复(2026-09-26)
对本 PR 做了一轮子智能体交叉审计,随后修复确认的问题:
tools/i18n-verify.mjs接入 CI(当前存在存量缺口,本次 8 个回归正是从该盲区漏掉的);parse_model_metadata_map归一化与前端对齐(同名变体后写者胜);RUNTIME_CACHE_ENV_LOCK,新增行内后缀优先级测试;.gitignore补.zcodetmp/。测试
cargo test -p codex-plus-core全部测试二进制通过(0 失败;CI 另有cargo test --workspace)cargo clippy -p codex-plus-core --all-targets无新增告警npm test274 用例全部通过,npm run check(tsc)无错误node tools/i18n-verify.mjs:本 PR 引入的 8 个 MISSING 已清零(余量为 main 存量)License
AGPL-3.0-only