fix(model-providers): 自定义模型缺省上下文窗口按 Registry 命中回填 - #3886
Conversation
自定义供应商的模型此前一律物化 200K 保守默认 contextWindow:官方端点 + 裸模型 id(如 glm-5.3)明明可用 1M,却先被 200K 兜底压住,claude-code 侧的 [1m] 后缀开关也随之失效,用户必须手填「上下文(tokens)」才能解锁 (见 makecindy#3883)。 改为:用户显式填写优先;缺省时若模型 ID 能命中 Model Registry 条目,回填 Registry 登记的窗口(perAgent 覆盖优先);仍未命中才落 200K。匹配与既有 registryEffortMetadata 同款两阶段——先精确(entry.id / route.modelId 原样 相等),仅精确无命中时再用网关前缀剥离(openai/xd/chatgpt)与命名空间条目 去前缀(自定义 "glm-5.3" ↔ 条目 "z-ai/glm-5.3")兜底。两阶段必须分开: 如 "gpt-5.5" 精确命中 openai/gpt-5.5,混入后缀兜底会捎上折扣档 xd/codex-gpt-5.5(272K),把本可回填的 1.05M 冲突成保守默认。 命中一致才采用:匹配不到、有条目未声明窗口、或多方窗口冲突时保持 200K 不动——Registry 窗口是产品目录写定的真实上限,错误回填比不填更糟。 配套语义: - 用户填写或 Registry 命中都标记 contextWindowVerified(显式声明的真实 上限,可供 resolveVerifiedContextWindow 收敛运行期上报窗口);纯 200K 兜底不标记(仅用于展示的保守默认)。 - contextWindowExplicit 仍只在用户显式填写时置位,编辑表单回转配置时 继续区分「显式值」与「回填/默认值」。 数据:catalog/model-registry.json 补登 z-ai/glm-5.3(1M,xd 路由, claude-code/codex),对齐 glm-5.2 条目形态。 测试:src/__tests__/user-provider.test.ts 新增 5 例——裸 id/命名空间 id 命中回填、perAgent 分 agent 窗口(gpt-5.5: claude-code 1.05M / codex 272K)、网关前缀剥离命中、冲突与未声明窗口保持保守默认、显式填写压过 Registry 回填。包内 689 例全绿,tsc --noEmit 通过。 Closes makecindy#3883 Signed-off-by: 6theditioncn-hue <271904240+6theditioncn-hue@users.noreply.github.com>
|
| Filename | Overview |
|---|---|
| packages/model-providers/src/user-provider.ts | 新增 Registry 窗口两阶段回填,但后缀兜底绕过了当前 agent 的路由约束。 |
| packages/model-providers/src/tests/user-provider.test.ts | 新增五组主要回填语义测试,但未覆盖命名空间条目不支持当前 agent 的场景。 |
| packages/model-providers/catalog/model-registry.json | 新增 z-ai/glm-5.3 的 1M 窗口、effort、per-agent 与 xd 路由元数据,形态与相邻条目一致。 |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[自定义模型缺省 contextWindow] --> B{精确匹配当前 agent 路由}
B -->|命中| C[采用 perAgent 或顶层窗口]
B -->|未命中| D[剥离网关前缀并匹配命名空间后缀]
D --> E{条目支持当前 agent}
E -->|应当支持| F{窗口唯一且一致}
E -->|当前实现未检查| G[可能采用其他 agent 的窗口]
F -->|是| C
F -->|否| H[200K 保守默认]
C --> I[contextWindowVerified=true]
G --> I
I --> J[运行期使用已核实窗口]
Prompt To Fix All With AI
### Issue 1
packages/model-providers/src/user-provider.ts:202
**后缀匹配绕过路由约束**
Stage 2 的命名空间后缀分支没有校验条目是否支持当前 agent。例如,`codex` 下的裸 ID `gemini-3.5-flash` 会命中仅声明 `claude-code` 路由的 `google/gemini-3.5-flash`,并把 1M 标记为已核实窗口。`resolveVerifiedContextWindow` 随后会用它覆盖运行期上报值,可能高估实际能力并导致长会话被上游拒绝。后缀匹配也应要求 Registry 条目包含当前 agent;否则应继续使用保守默认。
```suggestion
(entry.routes.some((route) => route.agents.includes(agent)) &&
candidates.has(suffixAfterNamespace(entry.id))),
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(model-providers): 自定义模型缺省上下文窗口按 Regi..." | Re-trigger Greptile
| matches = registry.models.filter( | ||
| (entry) => | ||
| matchesEntry(entry, candidates) || | ||
| candidates.has(suffixAfterNamespace(entry.id)), |
There was a problem hiding this comment.
Stage 2 的命名空间后缀分支没有校验条目是否支持当前 agent。例如,codex 下的裸 ID gemini-3.5-flash 会命中仅声明 claude-code 路由的 google/gemini-3.5-flash,并把 1M 标记为已核实窗口。resolveVerifiedContextWindow 随后会用它覆盖运行期上报值,可能高估实际能力并导致长会话被上游拒绝。后缀匹配也应要求 Registry 条目包含当前 agent;否则应继续使用保守默认。
| candidates.has(suffixAfterNamespace(entry.id)), | |
| (entry.routes.some((route) => route.agents.includes(agent)) && | |
| candidates.has(suffixAfterNamespace(entry.id))), |
Knowledge Base Used: Model provider management
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/model-providers/src/user-provider.ts
Line: 202
Comment:
**后缀匹配绕过路由约束**
Stage 2 的命名空间后缀分支没有校验条目是否支持当前 agent。例如,`codex` 下的裸 ID `gemini-3.5-flash` 会命中仅声明 `claude-code` 路由的 `google/gemini-3.5-flash`,并把 1M 标记为已核实窗口。`resolveVerifiedContextWindow` 随后会用它覆盖运行期上报值,可能高估实际能力并导致长会话被上游拒绝。后缀匹配也应要求 Registry 条目包含当前 agent;否则应继续使用保守默认。
```suggestion
(entry.routes.some((route) => route.agents.includes(agent)) &&
candidates.has(suffixAfterNamespace(entry.id))),
```
**Knowledge Base Used:** [Model provider management](https://app.greptile.com/xindong/-/custom-context/knowledge-base/makecindy/cindy/-/docs/model-provider-management.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
@6theditioncn-hue 👋 这个 PR 还有 1 条 review conversation 没 resolve(packages/model-providers/src/user-provider.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
MagicLizi
left a comment
There was a problem hiding this comment.
Findings
- [P1] .github/PULL_REQUEST_TEMPLATE.md:1 — Description 缺模板要求的三段:这次改了什么 / 怎么验证的 / 风险。当前描述无法对照 diff 核对范围与验证,请按仓库 PR 模板补全这三段后再请求审查。
维护者确认门(arch:core-paths)本轮按「同结构内的实现回填 / bugfix」语义豁免,不创建 hold;格式门未过,先打回补描述。
Overall — changes-requested
|
@6theditioncn-hue 👋 这个 PR 目前与 请在本地 merge 最新的 |
fix(model-providers): 自定义模型缺省上下文窗口按 Registry 命中回填
Closes #3883
问题
自定义供应商的模型此前一律物化 200K 保守默认
contextWindow。用户走官方端点 + 裸模型 id(如智谱官方 Anthropic 兼容端点 +glm-5.3)时,模型实际可用 1M 上下文,却先被 200K 兜底压住:[1m]后缀开关随物化窗口(< 1e6)被剥离,1M 形同虚设;方案
buildUserProvider物化模型元数据时,缺省contextWindow改为按 Model Registry 回填:匹配沿用既有
registryEffortMetadata的两阶段结构:entry.id/route.modelId原样等于模型 ID;openai/xd/chatgpt/)+ 命名空间条目去前缀(自定义glm-5.3↔ 条目z-ai/glm-5.3)。两阶段必须分开:
gpt-5.5精确命中openai/gpt-5.5,若混入后缀兜底还会捎上折扣档xd/codex-gpt-5.5(272K),把本可回填的 1.05M 冲突成保守默认。保守性:匹配不到、命中条目未声明窗口、或多方窗口冲突时,一律保持 200K 不回填——Registry 窗口是产品目录写定的真实上限,错误回填(高估导致会话中后段 400)比不填(仅浪费可用窗口)更糟。
配套语义:
contextWindowVerified: true(显式声明的真实上限,可供resolveVerifiedContextWindow收敛运行期上报的窗口);纯 200K 兜底不标记(仅用于展示的保守默认)。contextWindowExplicit仍只在用户显式填写时置位——编辑表单回转配置时继续区分「显式值」与「回填/默认值」,未来默认升级后显式值原样保留。数据:catalog/model-registry.json 补登
z-ai/glm-5.3(contextWindow 1M,xd 路由 claude-code/codex,perAgent claude-code efforts),形态对齐既有z-ai/glm-5.2条目。效果(以 #3883 场景为例)
glm-5.3+ 官方端点,未填窗口[1m]被剥离)gpt-5.5,claude-code / codexglm-5.3-flash)测试
src/__tests__/user-provider.test.ts新增 5 例:裸 id / 命名空间 id 命中回填、perAgent 分 agent 窗口、网关前缀剥离命中、冲突与未声明窗口保持保守默认、显式填写压过 Registry 回填;packages/model-providers全量 689 例通过,tsc --noEmit通过。