Skip to content

fix(proxy): 模型列表端点不再被 openai_chat_compatible 能力误拦#202

Merged
g1331 merged 1 commit into
masterfrom
hotfix/proxy-models-list-capability
Jun 2, 2026
Merged

fix(proxy): 模型列表端点不再被 openai_chat_compatible 能力误拦#202
g1331 merged 1 commit into
masterfrom
hotfix/proxy-models-list-capability

Conversation

@g1331

@g1331 g1331 commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Summary

修复一个生产环境暴露的矛盾:仅绑定 Codex 形态上游(openai_responses / codex_cli_responses)的密钥能够正常调用模型,但调用 GET /v1/models 列模型时却返回 403 NO_AUTHORIZED_UPSTREAMS。根因是模型列表这个发现类端点被硬编码判定为 openai_chat_compatible 能力,并且本地模型列表处理逻辑被放在了能力授权拦截之后,导致非 chat 能力的密钥永远走不到本应为它服务的本地返回逻辑。

Related Issue

无关联 issue,源自生产日志排查(请求 request_id=6614756f,路径 modelscapabilityCandidatesCount:1 / authorizedCapabilityCandidatesCount:0)。

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Tests (adding or updating tests)

Changes

src/app/api/proxy/v1/[...path]/route.ts 中的「本地模型列表」短路逻辑从能力授权拦截之后前移到之前,并把可见模型的过滤基准从「openai_chat_compatible 授权候选」改为「密钥实际授权的全部 active 上游(不限能力)」。

行为约定保持收敛:仅当密钥配置了 allowed_models 且至少存在一个授权的 active 上游时,才本地返回模型列表;若密钥没有任何授权 active 上游,则继续走原有拦截返回 403,原「无授权上游」语义不变。未配置 allowed_models 的密钥仍按原逻辑转发上游,不受影响。

Test Plan

  • Local tests pass:pnpm test:run tests/unit/api/proxy/route.test.ts(74 passed / 1 skipped),含新增回归用例「密钥仅绑定不支持 openai_chat_compatible 的上游时,GET /v1/models 返回 200 本地列表而非 403」
  • Type check passes:pnpm exec tsc --noEmit
  • Lint passes:ESLint + Prettier 对改动文件均通过
  • Manual testing completed(生产侧待部署后验证)

Checklist

  • Code follows the project's coding standards
  • Tests have been added where necessary
  • Documentation has been updated (if applicable)
  • Changes do not introduce security vulnerabilities
  • Commit messages follow conventions

Additional Notes

并存的次要观察(本 PR 未一并处理,避免扩大改动范围):NO_AUTHORIZED_UPSTREAMS 拦截分支(route.ts 内)只打 log.warn 后直接 return,未调用 logRequest 落库,因此这类 403 不会出现在管理后台请求日志里,仅存在于容器 stdout。与之相邻的 NO_UPSTREAMS_CONFIGURED 分支却会落库。这是一处可观测性上的落库不一致,可在后续单独评估是否补齐。

GET /v1/models 是发现类端点,原先被硬编码判定为 openai_chat_compatible
能力,并在授权拦截之后才执行本地模型列表处理。导致仅绑定 Codex 形态上游
(openai_responses / codex_cli_responses)的密钥即便能正常调用模型,也会
在列模型时收到 403 NO_AUTHORIZED_UPSTREAMS,形成“能用却列不出”的矛盾。

将本地模型列表短路逻辑前移到能力授权拦截之前,并按密钥实际授权的全部
active 上游(不限能力)过滤可见模型。只要密钥配置了 allowed_models 且至少
有一个授权 active 上游,即本地返回模型列表,与具体路由能力解耦。

补充回归测试:密钥仅绑定不支持 openai_chat_compatible 的上游时,GET
/v1/models 返回 200 本地列表而非 403。
@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.44%. Comparing base (bee51e7) to head (43edf9b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #202      +/-   ##
==========================================
- Coverage   74.45%   74.44%   -0.01%     
==========================================
  Files         160      160              
  Lines       11626    11626              
  Branches     3982     3982              
==========================================
- Hits         8656     8655       -1     
  Misses       1731     1731              
- Partials     1239     1240       +1     
Flag Coverage Δ
verify 74.44% <ø> (-0.01%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@g1331 g1331 merged commit fe154c9 into master Jun 2, 2026
12 checks passed
@g1331 g1331 deleted the hotfix/proxy-models-list-capability branch June 2, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant