feat: 自定义供应商缺少「模型是否支持图片输入」的显式声明,支持视觉的模型也看不到图片
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
**客户端版本**: 0.1.76
**OS**: win32 x64 (10.0.26200)
**界面语言**: zh-CN
**版本区域**: CN
---
## 使用场景 / Use case
我在「设置 → 模型供应商」里自建了供应商(鉴权 = API 密钥,Runtime = **Claude Code**,自填 baseURL),选的模型本身支持图片输入。贴图/截图后,我希望模型能直接看到原图。
实际表现(使用者反馈,0.1.76):这个组合下界面上没有任何地方能声明「该模型支持图片输入」,模型被按「未知 / 不支持图片」处理,支持视觉的模型也看不到图片。
## 当前问题 / Current limitation
### 1)「支持图片输入」开关只在 Pi runtime 出现,其它 runtime 没有声明入口
自定义供应商对话框里这个 checkbox 被包在 `activeTab === 'pi'` 的分支内:
- `apps/desktop/src/renderer/components/settings/CustomProviderDialog.tsx:2964` —— `{activeTab === 'pi' && (`,复选框本体在 `2998-3023`,绑定 `m.supportsImageInput`;
- setter:`apps/desktop/src/renderer/lib/customProviders.ts:121` `setCustomProviderModelSupportsImageInput`。
也就是说自定义供应商走 **Claude Code runtime**(Anthropic 协议)或 Codex runtime 时,模型行里只有「模型协议」「推理」这类 Pi 专属项,用户**没有任何地方**能声明某个模型支持图片输入。Codex + OpenAI Chat 的扩展目前还停在未合入的 PR #2698 / 待确认 #2738,且仍是二态布尔,同样不覆盖 Claude Code runtime。
### 2)没有显式声明时,「能不能看图」靠模型名前缀的硬编码名单推断
`packages/model-providers/src/visionCapability.ts` 的模块注释自己写明了这个前提:
> cindy 的模型目录(catalog / model-registry)目前**没有结构化**的「能否看图」元数据(modalities 只在 Pi 自定义 provider 手动标记,内置目录为空)。
于是 `classifyVisionCapability()` 只能按一份保守前缀名单判定:
- `no-vision`:`deepseek/deepseek-`、`deepseek-`、`z-ai/glm-5.2`、`glm-5.2`;
- `vision`:`claude-`、`gpt-`、`gemini-`、`grok-`、`qwen*-vl`、`kimi-k2-vision` 等;
- 其余一律 `unknown`,按保守处理。
### 3)后果
模型 id 不在名单里、但确实是多模态的情况很常见(第三方网关、聚合平台、自建中转的命名五花八门,常带命名空间/`-flash`/日期等后缀),这类模型会被当成「未知 / 不支持图片输入」:
- 「模型高级」抽屉里「图片输入」显示为「不支持 / 未声明」,而且是**只读**(`apps/desktop/src/renderer/components/settings/ModelAdvancedDrawer.tsx:301-310, 754-768`)——用户既看不出这个判定从哪来,也改不了;
- 视觉桥「未自定义时默认勾选」会把该模型当纯文本模型(同文件注释;消费点 `apps/desktop/src/main/vision-bridge/vision-bridge.ts` 的 `isKnownNoVisionModel`)。启用视觉桥后,贴的图会**先被转成文字描述再喂给模型**,原图信息就丢了 —— 表现正是「本来支持视觉的模型看不到图片」。
这个坑项目自己已经踩过一次:同文件注释记录了 2026-09-04「实测四个型号全部误判」,之后才补了 `vision` / `vl` 型号名标记兜底。只靠名字名单,注定追不上各家新模型的命名。
## 期望方案 / Proposed solution
1. **把按模型的「支持图片输入」声明补到所有自定义供应商 runtime**(Claude Code / Anthropic 协议这条最缺,Codex 与 Pi 一并对齐),复用已有字段 `ProviderRuntimeModelConfig.supportsImageInput`。
2. **改为三态显式声明**:`跟随判定(auto)/ 支持图片输入 / 不支持图片输入`。显式值优先级最高、压过名字名单,即把 `classifyVisionCapability()` 的判定顺序改为「用户显式声明 > 型号名显式标记(`vision` / `vl`) > 家族前缀名单 > unknown」。
3. **在「模型高级」抽屉里标注判定来源**(「你已声明」/「按模型名推断」/「未知,按保守处理」)并允许就地修改,让用户能自行纠偏。
## 已考虑的替代方案 / Alternatives considered
- **只扩名字前缀名单**:治标。聚合平台与自建网关的型号名追不完,2026-09-04 的四型号误判已经说明这条路会持续失守。
- **只靠 `modalities` 元数据**:需要上游返回结构化 modality(#3422 的方向),自建 / 中转供应商多数拿不到,离线也不可用,仍需手动兜底。
- **只用视觉桥绕过**:视觉桥是把图转成文字描述给纯文本模型用;真多模态模型本该直接吃原图,走桥反而丢信息。
## 关联
- #2738 / PR #2698:把「支持图片输入」开关从 Pi 扩到 Codex OpenAI Chat,尚未覆盖 Claude Code runtime,且仍是二态布尔。
- #2371(openai-chat 桥接硬编码白名单丢图)、#593、#2133、#2832、#2416
- #2544(视觉桥方向)、#3422(模型元数据自动展示)、#3564(自定义供应商配置界面简化)
Contributor guide
Research direction
Start with `CustomProviderDialog.tsx` and `customProviders.ts` to trace the existing `supportsImageInput` setting, then read `visionCapability.ts` and `ModelAdvancedDrawer.tsx` for current classification and display behavior. The issue also points to `vision-bridge.ts` as a consumer. Done means custom-provider runtimes can explicitly set image support or defer to automatic detection, and the advanced drawer shows the detection source and allows correction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- ai, frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100