Hermes WebUI 8787 cpa-codex 模型目录错位复盘
本轮调整尚未真正收口。已修复的是 custom:cpa-codex 的默认模型/provider 粘连与同名模型 provider 丢失问题,但模型目录展示仍有策略错误:WebUI 当前把 CPA live aliases 与 config.yaml 中的静态 configured models 当成互斥来源处理,导致 gpt-5.4 / gpt-5.3-codex / gpt-5.2 等静态模型没有显示,同时动态 alias 又未按预期与静态列表做并集。
先不要宣称 8787 已完全修好;下一步应把 cpa-codex 的模型目录合并策略改成“live aliases ∪ configured models ∪ active/default sticky entries”,并补回归测试覆盖 CPA 动态 alias 与静态模型共存。
当前 ~/.hermes/config.yaml 的 cpa-codex.models 仍包含 gpt-5.4 / gpt-5.5 / gpt-5.4-mini / gpt-5.3-codex / gpt-5.2,但 WebUI get_available_models() 当前 custom:cpa-codex 分组只显示 10 个 live alias / sticky 模型,如 gpt-5.5-high / gpt-5.5-xhigh / claude-opus-4-8 / SC-GPT-5.5(high) / JUN-GPT-5.5(high) / ANY-5.5(high),未显示 gpt-5.4 / gpt-5.3-codex / gpt-5.2。
先把已验证方案当成稳定基线:保留当前 schedule / deliver / workdir,不急着继续扩面;新增候选先读源码、看 output、做 run-now 验证,再决定是否转 script-only。
证据摘要
- 当前
~/.hermes/config.yaml的cpa-codex.models仍包含gpt-5.4 / gpt-5.5 / gpt-5.4-mini / gpt-5.3-codex / gpt-5.2,但 WebUIget_available_models()当前custom:cpa-codex分组只显示 10 个 live alias / sticky 模型,如gpt-5.5-high / gpt-5.5-xhigh / claude-opus-4-8 / SC-GPT-5.5(high) / JUN-GPT-5.5(high) / ANY-5.5(high),未显示gpt-5.4 / gpt-5.3-codex / gpt-5.2。
行动清单
gpt-5.5-high / SC-GPT-5.5(high) / ANY-5.5(high);gpt-5.4 / gpt-5.3-codex / gpt-5.2;model_catalog: configured 或 models_source: configured 时;边界 / 风险
CPA 这类 aggregator / proxy gateway 的 alias 可能动态变化,配置里的 models 又代表用户主动声明。二者互斥会导致一边总是缺失。
当前 api/config.py unstaged 改动已经明显倾向 live catalog 优先、configured fallback。这正是当前缺 gpt-5.4 / gpt-5.3-codex / gpt-5.2 的原因之一。
51 passed 只覆盖路由和 JS 行为,不能覆盖完整模型目录源合并。验收必须包含 get_available_models() 的 provider 分组内容。
CPA /v1/models 裸请求返回 401。后续要验证 live aliases,应走 WebUI/Hermes 内部 provider connection 或带正确 API key 的请求。
完整记录
Hermes WebUI 8787 cpa-codex 模型目录错位复盘
背景
涛哥反馈:8787 WebUI 的对话里选择模型时,cpa-codex 这个 provider 下的“模型显示”和“实际使用”不一致。第一次处理后,我误判为已经调整好;涛哥随后指出仍不对:
cpa-codex里目前没有gpt-5.3-codex、gpt-5.2、gpt-5.4这些模型;- 还有好几个别的模型 alias,也没有按预期显示出来;
- 需要把已做内容整理写入 Wiki 并发布 HTML。
本记录用于留档:明确已做、误判点、当前实际状态、下一步应修方向。
当前时间与环境
- 巡检时间:2026-06-04 22:44:56 CST
- 服务:
hermes-webui-8787.service - 项目路径:
/home/ht/.hermes/external-projects/hermes-webui - 当前 workspace:
/home/ht/workspace - WebUI 运行态:8787 服务已重启并处于 active running
- 当前会话模型默认配置:
model.default = SC-GPT-5.5(high),model.provider = custom:cpa-codex
已做内容
1. 后端 provider 路由修正
针对默认模型和同名模型跨 custom provider 的冲突,修改了 api/config.py 中的 resolve_model_provider() 逻辑:
- 当
model.provider = custom:cpa-codex且默认模型是SC-GPT-5.5(high)时,解析结果应保持在custom:cpa-codex; - 对
custom_providers[].models支持 list 形态,不只支持 dict; - 避免同名模型例如
gpt-5.5被后面的其他 custom provider 覆盖。
已观察到的解析结果:
这部分说明:实际路由层大体已经能把这些模型解析到 cpa-codex。
2. 前端 option provider 上下文修正
修改了 static/ui.js:
populateModelDropdown()生成<option>时写入data-provider;_addLiveModelsToSelect()加 live model 时也写入data-provider;- 目的是避免多个 provider 下有同名模型时,前端只凭
option.value选中第一项,导致 provider 丢失。
这部分解决的是:下拉选项值相同但 provider 不同的歧义。
3. 静态资源缓存 bust
修改了 api/routes.py:
- 新增
_webui_asset_version_token(); - 将静态文件 mtime 纳入
/,/login,/sw.js的版本 token; - 目的:本地热修
static/ui.js/style.css后,移动端/PWA 缓存能更快刷新。
这部分不是模型目录主因,但有助于避免“代码改了前端还用旧 JS”的假阴性。
4. 测试补充
新增或修改了相关测试:
tests/test_custom_provider_default_routing.pytests/test_renderer_js_behaviour.pytests/test_pwa_manifest_sw.pytests/test_issue2540_models_endpoint_error.py中新增了模型目录来源策略相关测试草案
已跑过的窄测试:
这个测试结果只证明默认路由和部分 JS 行为通过,不能证明 cpa-codex 模型目录已完整正确。此前把它当成“已完全修好”的依据,是误判。
当前实际状态
Hermes 配置里的 cpa-codex 静态模型
~/.hermes/config.yaml 中 custom_providers 是 list 形态,cpa-codex 当前配置摘要如下:
说明:从配置源看,gpt-5.4 / gpt-5.3-codex / gpt-5.2 并没有被删除。
WebUI 当前 get_available_models() 展示结果
当前 get_available_models() 返回的 custom:cpa-codex 分组是:
没有出现:
这与涛哥反馈一致:模型目录展示仍然不完整。
直接访问 CPA /v1/models 的限制
裸请求:
返回:
说明:不能用不带鉴权的裸 curl / urllib 结果判断 CPA 实际模型目录。WebUI 内部能读到 live aliases,是因为它走了 custom provider connection / api key 解析链路。
根因判断
当前问题不是单一 bug,而是两类模型来源没有统一:
- configured models:来自
~/.hermes/config.yaml的custom_providers[].models,代表本地静态配置/用户声明; - live aliases:来自 CPA
/v1/models的动态 alias,代表 CPA 当前可暴露模型; - sticky default/active model:来自
model.default+model.provider,必须保证当前默认模型可见。
此前 unstaged 修改把策略改成:
这会导致当前现象:当 CPA live catalog 返回成功时,静态配置里的 gpt-5.4 / gpt-5.3-codex / gpt-5.2 不再进入下拉列表。
涛哥当前期望更接近:
也就是:不是 live 替代 config,也不是 config 替代 live,而是要合并,并稳定去重。
当前工作区状态
仓库路径:/home/ht/.hermes/external-projects/hermes-webui
当前存在 staged 与 unstaged 两层改动:
staged 文件
unstaged 文件
重要提醒
api/config.py 的 unstaged 部分包含“live catalog wins over stale configured models”的方向,这与当前反馈冲突。后续修复前建议不要直接提交这层 unstaged 改动,应先改为 union 策略或回退再重做。
建议下一步修复策略
推荐策略
把 get_available_models() 中 named custom provider 的模型合并逻辑改成:
建议补的回归测试
至少补三组:
- live + configured 并集
- live 返回:
gpt-5.5-high / SC-GPT-5.5(high) / ANY-5.5(high); - config 包含:
gpt-5.4 / gpt-5.3-codex / gpt-5.2; - 期望下拉同时包含两边。
- configured catalog opt-in
- 当 provider 写
model_catalog: configured或models_source: configured时; - 不 probe
/v1/models,只展示 configured models + sticky default。
- 同名模型 provider 不丢失
custom:cpa-codex与custom:yt都有gpt-5.5;- 选择 cpa-codex 下的
gpt-5.5后,发送 payload 必须带model_provider=custom:cpa-codex。
风险与边界
风险 1:继续把 live 与 configured 做互斥会反复漏模型
CPA 这类 aggregator / proxy gateway 的 alias 可能动态变化,配置里的 models 又代表用户主动声明。二者互斥会导致一边总是缺失。
风险 2:直接提交当前 unstaged 改动会固化错误策略
当前 api/config.py unstaged 改动已经明显倾向 live catalog 优先、configured fallback。这正是当前缺 gpt-5.4 / gpt-5.3-codex / gpt-5.2 的原因之一。
风险 3:只看 200 OK 或窄测试会误判
51 passed 只覆盖路由和 JS 行为,不能覆盖完整模型目录源合并。验收必须包含 get_available_models() 的 provider 分组内容。
风险 4:裸访问 CPA /v1/models 会因鉴权失败产生假结论
CPA /v1/models 裸请求返回 401。后续要验证 live aliases,应走 WebUI/Hermes 内部 provider connection 或带正确 API key 的请求。
验收标准
修复完成后,至少满足:
get_available_models()的custom:cpa-codex分组同时包含:
- live aliases:如
gpt-5.5-high / gpt-5.5-xhigh / SC-GPT-5.5(high) / JUN-GPT-5.5(high) / ANY-5.5(high); - configured models:
gpt-5.4 / gpt-5.3-codex / gpt-5.2 / gpt-5.4-mini / gpt-5.5。
- 前端下拉每个 option 都带正确
data-provider。 - 发送消息 payload 中携带
model_provider=custom:cpa-codex。 - 服务重启后 8787 日志中 reasoning/chat 请求仍为:
model=<用户选择的模型>;provider=custom:cpa-codex。
- 回归测试覆盖 live + configured union,而不是只覆盖默认路由。
行动清单
- 先把当前 unstaged 的 live-only 策略改成 union 策略,或回退后重做。
- 补
test_named_custom_provider_live_catalog_merges_configured_models,明确验证 live aliases 与 configured models 并集。 - 保留
data-provider前端修正,继续防止同名模型 provider 丢失。 - 修完后重启
hermes-webui-8787.service,并用 fresh Python process 验证get_available_models()。 - 最终验收不能只看测试通过,要打印
custom:cpa-codex分组完整模型列表。
完整记录
本轮主要事实:
- 已修的方向:默认模型/provider 路由、前端 option provider 上下文、静态资源缓存 bust。
- 误判的地方:把路由修复 + 窄测试通过当成“模型目录完全正确”。
- 当前真实问题:
get_available_models()的模型目录来源合并策略仍不对。 - 当前建议:将
cpa-codex目录改成 live aliases、configured models、sticky default 的稳定并集。
本记录不是最终修复报告,而是阶段复盘和后续修复指引。