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。
c30c480 to
d4eaf59
Compare
|
改动已合入 说明:合入时对分支做了 rebase, 解冲突时做的一处取舍,请确认
我保留了你的来源名结构(徽标「匹配:{0}」需要它),并做了两件补充:
如果你认为 验证前端 296 passed、Rust 1556 passed / 0 failed; |
一句话总结
这个 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