Skip to content

fix: 修复 Gemini 风格 /v1/models 列表请求 - #6199

Merged
seefs001 merged 2 commits into
QuantumNous:mainfrom
zhibisora:zhibisora/realtime-fork-sync
Aug 11, 2026
Merged

fix: 修复 Gemini 风格 /v1/models 列表请求#6199
seefs001 merged 2 commits into
QuantumNous:mainfrom
zhibisora:zhibisora/realtime-fork-sync

Conversation

@zhibisora

@zhibisora zhibisora commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

修复 Gemini 风格的 GET /v1/models 列表请求:

  • 让认证中间件在不带尾斜杠的 /v1/models 上读取 x-goog-api-keykey 查询参数。
  • 将 Gemini 列表请求交给 ListModels,避免因缺少 :model 参数进入 RetrieveModel 并返回空模型名错误。
  • 添加 HTTP 回归测试,覆盖 OpenAI Bearer、Gemini x-goog-api-key?key= 的响应契约。

AI disclosure: 本次修改由 AI 辅助分析、实现和测试,请维护者按常规流程审阅。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

$ go test ./router -run TestListModelsSupportsOpenAIAndGeminiAuthentication -v
--- PASS: TestListModelsSupportsOpenAIAndGeminiAuthentication
    --- PASS: TestListModelsSupportsOpenAIAndGeminiAuthentication/OpenAI_bearer_token
    --- PASS: TestListModelsSupportsOpenAIAndGeminiAuthentication/Gemini_API_key_header
    --- PASS: TestListModelsSupportsOpenAIAndGeminiAuthentication/Gemini_API_key_query
PASS

$ go test ./middleware ./router
ok  github.com/QuantumNous/new-api/middleware
ok  github.com/QuantumNous/new-api/router

$ go test ./...
PASS

本地启动完整 HTTP 服务后的实际请求结果:

Authorization: Bearer <key>  -> 200 {"data":[],"object":"list","success":true}
x-goog-api-key: <key>        -> 200 {"models":[],"nextPageToken":null}
/v1/models?key=<key>         -> 200 {"models":[],"nextPageToken":null}
未携带任何凭据               -> 401 Invalid token

Summary by CodeRabbit

  • Bug Fixes

    • Updated model authentication logic so /v1/models properly recognizes and handles Gemini API key input from headers and key query parameters.
    • Adjusted the Gemini-specific behavior of the root models endpoint to return a model list (instead of a single-model result).
  • Tests

    • Added coverage for GET /v1/models validating successful responses for OpenAI bearer auth, Gemini header auth, and Gemini ?key=... query auth.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The /v1/models authentication path now recognizes Gemini API keys, and the Gemini route returns model lists through ListModels. Tests cover OpenAI bearer and Gemini API-key requests with isolated SQLite setup.

Changes

Gemini models endpoint

Layer / File(s) Summary
Root models path authentication
middleware/auth.go
TokenAuth now includes the exact /v1/models path when extracting authentication keys.
Gemini model listing and coverage
router/relay-router.go, router/relay_router_test.go
Gemini /v1/models requests use ListModels; tests cover OpenAI bearer authentication, Gemini header authentication, and Gemini query authentication.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant TokenAuth
  participant RelayRouter
  participant ListModels
  Client->>TokenAuth: GET /v1/models with API key
  TokenAuth->>RelayRouter: authenticated request
  RelayRouter->>ListModels: list Gemini models
  ListModels-->>Client: model list response
Loading

Possibly related PRs

Suggested reviewers: seefs001

Poem

A rabbit hopped to /v1/models,
With Gemini keys in little scrolls.
Lists now bloom where errors grew,
Bearer and query keys pass through.
“Hop!” says the bun, “the tests are green!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address #6198 by enabling /v1/models Gemini auth and routing list requests to ListModels.
Out of Scope Changes check ✅ Passed The test additions and auth/query handling stay within the request to fix Gemini /v1/models behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题简洁且准确概括了本次修复的核心:Gemini 风格的 /v1/models 列表请求。
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
router/relay_router_test.go (1)

39-67: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding a test case for the key query parameter.

The PR objective explicitly mentions supporting the key query parameter for Gemini-style authentication. While header authentication is well-tested, adding a test case for the query parameter would ensure complete regression coverage of the newly added routing behavior.

💡 Proposed change to include a query parameter test
 	tests := []struct {
 		name           string
 		headerName     string
+		queryName      string
 		expectedObject string
 		expectedField  string
 	}{
 		{
 			name:           "OpenAI bearer token",
 			headerName:     "Authorization",
 			expectedObject: "list",
 			expectedField:  "data",
 		},
 		{
 			name:          "Gemini API key header",
 			headerName:    "x-goog-api-key",
 			expectedField: "models",
 		},
+		{
+			name:          "Gemini API key in query",
+			queryName:     "key",
+			expectedField: "models",
+		},
 	}
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			recorder := httptest.NewRecorder()
-			request := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
-			value := "modelstestkey"
-			if test.headerName == "Authorization" {
-				value = "Bearer " + value
-			}
-			request.Header.Set(test.headerName, value)
+			path := "/v1/models"
+			if test.queryName != "" {
+				path += "?" + test.queryName + "=modelstestkey"
+			}
+			request := httptest.NewRequest(http.MethodGet, path, nil)
+
+			if test.headerName != "" {
+				value := "modelstestkey"
+				if test.headerName == "Authorization" {
+					value = "Bearer " + value
+				}
+				request.Header.Set(test.headerName, value)
+			}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@router/relay_router_test.go` around lines 39 - 67, Add a table-driven case in
the relay router test’s existing tests loop for Gemini authentication via the
key query parameter, using the expected Gemini models response and constructing
the request URL with the key parameter instead of relying on a header. Keep the
existing Authorization and x-goog-api-key cases unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@router/relay_router_test.go`:
- Around line 39-67: Add a table-driven case in the relay router test’s existing
tests loop for Gemini authentication via the key query parameter, using the
expected Gemini models response and constructing the request URL with the key
parameter instead of relying on a header. Keep the existing Authorization and
x-goog-api-key cases unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c68f56b-e6f8-4226-bd96-e468b85bbde0

📥 Commits

Reviewing files that changed from the base of the PR and between b6b97a6 and cb1fa8a.

📒 Files selected for processing (3)
  • middleware/auth.go
  • router/relay-router.go
  • router/relay_router_test.go

@zhibisora

Copy link
Copy Markdown
Contributor Author

已补充 ?key= 查询参数的回归用例,并在本地启动完整 HTTP 服务验证 Bearer、x-goog-api-key?key= 和无凭据四种请求行为。相关测试与 go test ./... 均通过。

JacksonsY added a commit to JacksonsY/new-api that referenced this pull request Jul 19, 2026
移植自上游 PR QuantumNous#6199(issue QuantumNous#6198)。带 x-goog-api-key 头或 ?key= 的
/v1/models 请求原先走 RetrieveModel(单模型详情),对列表请求必错;
改为 ListModels 返回模型列表。同步在 TokenAuth 里放行精确路径
/v1/models 从 query 取 key(与 /v1beta 现状一致)。补三种鉴权
(OpenAI bearer / Gemini header / Gemini query)的路由契约测试。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@seefs001
seefs001 merged commit 3d5dc36 into QuantumNous:main Aug 11, 2026
1 check passed
0401lucky pushed a commit to 0401lucky/new-api that referenced this pull request Aug 16, 2026
* fix: support Gemini model listing on v1 route

* test: cover Gemini query key model listing
DayFliggy pushed a commit to DayFliggy/Ren2Hub that referenced this pull request Aug 17, 2026
* fix: support Gemini model listing on v1 route

* test: cover Gemini query key model listing

Upstream-Commit: 3d5dc36
330079598 pushed a commit to 330079598/new-api that referenced this pull request Aug 19, 2026
* fix: support Gemini model listing on v1 route

* test: cover Gemini query key model listing
biubiubiu125 pushed a commit to biubiubiu125/newapi that referenced this pull request Aug 29, 2026
* fix: support Gemini model listing on v1 route

* test: cover Gemini query key model listing
biubiubiu125 pushed a commit to biubiubiu125/newapi that referenced this pull request Aug 29, 2026
* fix: support Gemini model listing on v1 route

* test: cover Gemini query key model listing
biubiubiu125 pushed a commit to biubiubiu125/newapi that referenced this pull request Aug 29, 2026
* fix: support Gemini model listing on v1 route

* test: cover Gemini query key model listing
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.

bug: Gemini 风格 /v1/models 无法正确返回模型列表

2 participants