bug: OpenAI 图像分组看不到 GPT Image 2.5——服务端目录显式的旧 imageModels 挡掉内置 Registry 声明
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 问题描述 / What happened
**实际行为**:在 0.1.81 上,设置 → 模型供应商 → OpenAI 的「图像」分组里只有一条 **GPT Image 2**,看不到 PR #4220 声称补齐的 **GPT Image 2.5 Sunburst / Flare**。
**期望行为**:按照 #4220 的说明(`feat(models): 补齐 GPT Image 2.5 并让图像显示开关生效`),新用户/已升级用户在图像分组里应能看到 GPT Image 2.5 Sunburst 与 GPT Image 2.5 Flare。
`#4220` 的 diff 确实把这两条写进了客户端内置 Registry(`packages/model-providers/catalog/model-registry.json`,`routes[].agents: []` + `nativeApi: openai-images`),但**正常联网路径下它们不会出现在 UI 里**。
### 原因定位(读源码 + 实测,非猜测)
客户端目录来源优先级:`开发本地文件 → 公共 API → LKG → 旧 OSS → 内置 bundled`(`packages/model-providers/src/source.ts:589`)。
1. **Registry 层没问题**:`selectNewerModelRegistry` 按 `updatedAt` 取新的整份(`source.ts:528`)。内置 Registry `updatedAt=2026-09-11T06:45:19.551Z`,线上目录为 `2026-09-11T06:45:19.550Z`,内置更新,所以内置那份胜出,2.5 条目**在**。
2. **卡在 Provider 层**:线上目录的 `openai` 段**显式声明**了旧形状的媒体清单:
```json
"imageModels": [
{ "id": "openai/gpt-image-2", "name": "GPT Image Model",
"modalities": { "input": ["text", "image"], "output": ["image"] },
"officialDocs": "https://platform.openai.com/docs/guides/image-generation" }
]
```
而 Registry 声明的媒体条目只在 Provider **未声明**该字段时才会补进去(`packages/model-providers/src/providerMediaModels.ts:76`,条件 `existing === undefined`)。这也是既有契约:`docs/model-registry-v4-media.md:68-71` 写着「显式名单(包括 `[]`)决定成员,不被公共条目补回」。
3. **结果**:线上目录显式的旧 `imageModels` 挡掉了内置 Registry 里的 2.5,用户可见清单只剩 GPT Image 2。
### 实测证据
线上目录(Global 与 CN 两个区域,ETag 相同,`registrySchemaVersion=5`):
- `https://model-access.cindy.app/api/model-catalog/catalog?registrySchemaVersion=5`
- `https://model-access.cindy.com.cn/api/model-catalog/catalog?registrySchemaVersion=5`
两份都是:`modelRegistry.updatedAt = 2026-09-11T06:45:19.550Z`、88 条 `models`、**无任何条目带 `mode` 字段**、**无任何 `routes[].agents: []`**、`openai.imageModels` 仅上述 1 条旧条目。
即服务端目录仍停在 V4 媒体扩展**之前**的形状,与 `docs/model-registry-v4-media.md:94-96` 描述的「发布前继续返回旧形状」一致。
本机客户端日志确认实际来源是远端,而非内置:
```text
[provider-service] [model-providers] loaded catalog from remote
{ url: 'https://model-access.cindy.com.cn/api/model-catalog/catalog' }
```
## 环境 / Environment
- Cindy 版本或 commit / version or commit: 0.1.81(`resources/cindy-source.json` → `sourceCommit: db19a86bf319b195763d9929dd436a0844d4587f`)
- 平台与版本 / platform & OS version: Windows 10 (10.0.19045) x64
- 安装方式 / install method: 官方安装包(`%LOCALAPPDATA%\Programs\Cindy`)
- 客户端目录缓存:`%APPDATA%\Cindy\cache\model-catalog\620708874c740c9ba142c942.json`
## 复现步骤 / Steps to reproduce
1. 使用 0.1.81(或任何含 #4220 的版本)启动 Cindy Desktop,确认已连接 OpenAI(ChatGPT 订阅)。
2. 进入 设置 → 模型供应商,左栏选择 **OpenAI**。
3. 在模型列表上方选择 **图像** 筛选项。
4. 观察分组内容:只有 **GPT Image 2** 一行,没有 GPT Image 2.5 Sunburst / Flare。
补充定位方法(只读,不改产品状态):
- 抓 `%APPDATA%\Cindy\logs\main-*.log`,搜索 `loaded catalog from remote`,确认目录来自远端。
- 读取 `%APPDATA%\Cindy\cache\model-catalog\*.json` 最新一份,检查 `providers[openai].imageModels` 与 `modelRegistry.updatedAt`,可复现上述形状差异。
## 期望修复
按 `docs/dev-rules/model-catalog-maintenance.md:86-87`「先维护 Server 正本,再协调客户端离线 Registry」,在 **model-access-server** 侧把 `openai` 段按 V4 媒体规范发布,二选一:
- 省略 `openai.imageModels`,让客户端从 Registry 派生(`docs/model-registry-v4-media.md:70-71` 的推荐形态);或
- 显式补齐 `openai/gpt-image-2.5-sunburst`、`openai/gpt-image-2.5-flare` 两条(可顺带把 `GPT Image Model` 这个旧显示名对齐)。
另需确认一个契约问题:`source.ts:390-404` 为 `xd.embeddingModels` 专门加了「字段缺席时用内置补齐」的兜底,注释明确写了「旧结构把 bundled 的新字段整段遮掉 → 目录派生出空清单、能力等于没上线」;`inheritImage` 目前只对 `xai` 开,`openai` 不在内。请确认 openai 图像清单是有意排除还是遗漏——如果内置 Registry 已作为权威成员来源,这里也应同样兜底。
## 日志与截图 / Logs & screenshots
设置 → 模型供应商 → OpenAI → 图像分组截图(仅一条 GPT Image 2,开关已开,灰字说明为新文案「不会出现在对话模型选择中;开关控制图像、视频等功能是否列出」):
(已附本 Issue 描述中的实测数据;截图另行补充,不含凭证与个人数据。)
## 关联
- 引入该补齐的 PR:https://github.com/makecindy/cindy/pull/4220
- 相关规范:`docs/model-registry-v4-media.md`(发布前置条件)、`docs/dev-rules/model-catalog-maintenance.md`
- 同类先例:https://github.com/makecindy/cindy/issues/2597 (订阅侧可用但目录清单未跟进)
Contributor guide
Research direction
Start with packages/model-providers/src/source.ts and packages/model-providers/src/providerMediaModels.ts, then read docs/model-registry-v4-media.md and docs/dev-rules/model-catalog-maintenance.md. Update the server catalog according to the V4 media contract, verify the remote OpenAI catalog exposes both GPT Image 2.5 entries, and confirm the client displays them without breaking explicit provider lists.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100