[Bug] 自定义 OpenAI-Compatible 模型的思考档位从不发送 reasoning_effort:档位→协议参数映射仅按模型家旭白名单合成,非白名单模型(grok/自建模型)被静默丢弃
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
提交前确认 · Pre-submission checklist
- 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate.
- 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category
模型设置 / 切换 · Model config
涉及的 Agent 框架 · Agent framework
ZCode Agent(自研)
严重程度 · Severity
阻塞使用 · Blocking (无法使用核心功能 / core function unusable)
复现频率 · Reproducibility
必现 · Always
问题描述 · Description
模型设置中的"思考档位"对非白名单模型完全失效——UI 可正常选择 low/medium/high/xhigh,但出站请求体从不包含 reasoning_effort,无任何提示。原因是"档位→协议参数"映射只按模型 ID 家族正则(gpt/glm/claude/opus-4.7/deepseek/kimi)自动合成,没有通用兜底。
- openai-compatible Chat Completions 适配器把 providerOptions 中的 reasoningEffort 序列化为 reasoning_effort;档位无映射时该值为 undefined,JSON.stringify 直接丢键,静默无警告。
- UI 档位列表(reasoning.levels / 用户配置 variants)与档位→协议参数映射(reasoning.providerOptionsByLevel)是两套数据;后者只由 resolveModelCapabilityDefaults 规则表按模型家族正则合成,replaceReasoning:true 还会覆盖用户显式配置。3.9.1 实际行为:非官方 openai 供应商且 ID 含 "gpt" → 档位 [low,medium,high,xhigh](不含 max,即此前"Max 选择后不转发"的同族根因);glm-5.2 → [max,high,nothink] 映射齐全;glm-5.3 → [low,high,max] 映射齐全(默认 max);claude / opus-4.7(含 max)/ deepseek / kimi-k3 各有映射;其余模型无任何规则 → 映射为空 → 档位不产生任何协议参数。
- 同一个 UI 控件的出站行为取决于隐藏的家族正则,用户不可见、不可控。
复现步骤 · Steps to reproduce
- 添加任意 openai-compatible 供应商,创建模型 ID 不含 gpt/glm/claude/opus/deepseek/kimi 字样的模型(grok-4.6 或本地 vLLM/Ollama 自命名模型);
- 模型设置中声明思考档位,UI 档位选择器正常出现;
- 会话切换到该模型,任选档位发起请求;
- 在网关侧/抓包查看出站 POST /v1/chat/completions 请求体。
期望表现 · Expected behavior
- 通用兜底:openai-compatible 模型声明了思考档位但无 providerOptionsByLevel 时,默认按 {openaiCompatible:{reasoningEffort:<档位>}} 发送,家族规则仅作覆盖/增强;
- 若某档位确定不会发送,请在 UI 或日志明确警告,而非静默丢弃;
- 统一 max:gpt 家族档位数组与 canonical reasoningEffort 枚举(当前 none/minimal/low/medium/high/xhigh)补上 "max",与 glm-5.2/5.3、opus-4.7 规则对齐;
- 用户显式配置的 providerOptionsByLevel 建议优先于家族默认(当前 replaceReasoning 会覆盖用户配置)。
实际表现 · Actual behavior
请求体中完全没有 reasoning_effort 字段,换任何档位都一样;网关后台确认未收到。已排除传输层:绕过本地代理直连官方 API 依旧复现;同一网关用 curl 手动带 reasoning_effort 可正常送达并被上游应用(reasoning_tokens 随之变化)。同供应商下 ID 含 "gpt" 的模型档位正常发送,可对照。
ZCode 版本 · ZCode version
3.9.1 (3.9.1.5853)
设备 / 系统 / 浏览器 · Device / OS / Browser
macOS Apple Silicon
截图 / 录屏 / 日志 · Screenshots / Recordings / Logs
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with resolveModelCapabilityDefaults and the OpenAI-compatible Chat Completions adapter, then trace how reasoning.levels, providerOptionsByLevel, and replaceReasoning affect the outgoing request. Done means declared levels produce reasoning_effort for unlisted models, explicit providerOptionsByLevel is retained, and unsupported levels are not silently discarded; the requested max alignment should also be checked.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100