Skip to content

Fix Gemini models list metadata#5000

Open
Y1nshe wants to merge 3 commits into
QuantumNous:mainfrom
Y1nshe:codex/fix-gemini-model-metadata
Open

Fix Gemini models list metadata#5000
Y1nshe wants to merge 3 commits into
QuantumNous:mainfrom
Y1nshe:codex/fix-gemini-model-metadata

Conversation

@Y1nshe
Copy link
Copy Markdown

@Y1nshe Y1nshe commented May 20, 2026

Summary

  • Populate Gemini-compatible GET /v1beta/models responses with non-empty supportedGenerationMethods
  • Return Gemini model names in the official models/{id} shape while keeping displayName as the plain model id
  • Use the existing endpoint capability metadata where possible, with Gemini-native fallbacks for text, embedding, Imagen, and Veo model families
  • Add controller coverage for Gemini model list metadata

Fixes #3365.

Tests

  • ~/go/bin/go1.25.1 test ./controller
  • ~/go/bin/go1.25.1 test ./router

Summary by CodeRabbit

  • New Features

    • Gemini models in API responses now include a normalized model identifier and matching display name.
    • Gemini models now report their supported generation methods (e.g., embedding, video, predict) for clearer client behavior.
  • Tests

    • Added test coverage validating Gemini model normalization and supported generation method reporting.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5f57a7b5-0b7c-4c23-87ea-7c389cc2fd54

📥 Commits

Reviewing files that changed from the base of the PR and between 0a354d6 and 161cd22.

📒 Files selected for processing (2)
  • controller/model.go
  • controller/model_list_test.go

Walkthrough

Populates Gemini /v1beta/models responses: refines DTO to use string arrays, adds buildGeminiModel to normalize model names/display names and compute SupportedGenerationMethods from ID prefixes and supported endpoint types, wires it into ListModels, and adds tests validating behavior.

Changes

Gemini Model Metadata Population

Layer / File(s) Summary
DTO Schema Update
dto/pricing.go
GeminiModel.SupportedGenerationMethods changed from []interface{} to []string for typed JSON output.
Controller Integration & imports
controller/model.go
Adds strings import and replaces inline Gemini model construction in ListModels with buildGeminiModel to emit normalized Name, DisplayName, and SupportedGenerationMethods.
Generation Method Derivation
controller/model.go
Adds buildGeminiModel and helpers: normalize model IDs to models/<normalized>, detect embedding/predict/video via ID prefixes for category fast paths, map SupportedEndpointTypes to generation methods with deduplication, and return a default when no endpoints match.
Test Infrastructure and Validation
controller/model_list_test.go
Adds geminiListModelsResponse, decodeGeminiListModelsResponse, geminiMethods, TestBuildGeminiModelNormalizesPrefixedID, TestGetGeminiSupportedGenerationMethodsUsesEndpointMetadata, and TestListModelsGeminiIncludesSupportedGenerationMethods to validate normalization and method sets in Gemini responses.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • QuantumNous/new-api#1547: Both PRs modify the Gemini ListModels behavior in controller/model.go and adjust the Gemini DTO in dto/pricing.go (including supportedGenerationMethods).
  • QuantumNous/new-api#2615: Both PRs touch Gemini model listing around /v1beta/models and related DTO parsing/population.
  • QuantumNous/new-api#1486: Related Gemini model-list handling and parsing changes that interact with the DTO and controller behavior.

Suggested reviewers

  • seefs001

Poem

🐰 I hopped through names both short and long,
I nudged each model to sing its song.
Prefix clues led me down the track,
Methods listed, no more lack—
Now Gemini models stride along.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix Gemini models list metadata' directly addresses the main change: populating missing metadata (supportedGenerationMethods and proper name formatting) in Gemini model list responses, which aligns with the PR's primary objective.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #3365: populates supportedGenerationMethods with proper values, formats model names as models/{id}, preserves displayName as plain id, uses endpoint metadata with fallbacks, and includes test coverage for Gemini model list metadata.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing Gemini model list metadata: normalizing model names and IDs, populating supportedGenerationMethods, updating the DTO schema, and adding corresponding test coverage; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@controller/model.go`:
- Around line 241-243: Replace the raw openAIModel.Id used for DisplayName with
the normalized ID so prefixed inputs are converted consistently: set DisplayName
to normalizeGeminiModelID(openAIModel.Id) (leave Name as
fmt.Sprintf("models/%s", normalizeGeminiModelID(openAIModel.Id))) so both fields
use the same normalized identifier; update the DisplayName assignment where the
struct is constructed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 213d9c7c-0394-42de-aea9-1c4babea008f

📥 Commits

Reviewing files that changed from the base of the PR and between 20d3e73 and dca82d4.

📒 Files selected for processing (3)
  • controller/model.go
  • controller/model_list_test.go
  • dto/pricing.go

Comment thread controller/model.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controller/model.go (1)

248-257: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reverse the priority: check endpoint metadata first, use prefix-based detection as fallback.

The function checks model ID prefixes (lines 250–257) with early returns before consulting SupportedEndpointTypes (lines 259–273). This contradicts the PR objective stating "prefer existing endpoint capability metadata where available; provide Gemini-native fallbacks."

The metadata is computed from channel abilities and passed to the function, but prefix-based detection always takes priority, meaning metadata configurations are silently ignored. Reorder the checks to validate SupportedEndpointTypes first, then fall back to prefix-based detection only if metadata is empty or absent.

🤖 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 `@controller/model.go` around lines 248 - 257, The function
getGeminiSupportedGenerationMethods currently prioritizes prefix-based detection
(normalizeGeminiModelID +
isGeminiVideoModel/isGeminiEmbeddingModel/isGeminiPredictModel) over endpoint
metadata; change it to first inspect openAIModel.SupportedEndpointTypes (and use
that to return the appropriate methods), and only if SupportedEndpointTypes is
empty or nil fall back to the existing prefix checks via normalizeGeminiModelID
and the isGemini* helpers; keep the same return values ("predictLongRunning",
"embedContent", "batchEmbedContents", "predict") and ensure the function still
returns nil when neither metadata nor prefix detection match.
🧹 Nitpick comments (2)
controller/model_list_test.go (2)

277-316: ⚡ Quick win

Consider adding test coverage for SupportedEndpointTypes mapping.

This test validates the prefix-based detection path (embedding/predict models), but doesn't cover the SupportedEndpointTypes → generation methods mapping (lines 259-268 in model.go).

Consider adding test cases for:

  • A non-prefixed model with SupportedEndpointTypes = [EndpointTypeGemini] should get ["generateContent"]
  • A non-prefixed model with SupportedEndpointTypes = [EndpointTypeEmbeddings] should get ["embedContent", "batchEmbedContents"]
  • A non-prefixed model with empty endpoint types should get the fallback ["generateContent"]

This would ensure the endpoint types logic is properly exercised.

🤖 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 `@controller/model_list_test.go` around lines 277 - 316, Add test cases
exercising the SupportedEndpointTypes → generation methods mapping by extending
TestListModelsGeminiIncludesSupportedGenerationMethods (or adding a new test) to
create non-prefixed model entries (no "gemini-" prefix) and set their
SupportedEndpointTypes on the model records: one with SupportedEndpointTypes =
[]string{model.EndpointTypeGemini} and assert
geminiMethods(models["models/<name>"]) returns ["generateContent"], one with
SupportedEndpointTypes = []string{model.EndpointTypeEmbeddings} and assert it
returns ["embedContent","batchEmbedContents"], and one with
SupportedEndpointTypes = []string{} (or nil) and assert the fallback
["generateContent"] is returned; use the same DB setup,
model.InvalidatePricingCache/GetPricing flow and require.ElementsMatch
assertions as in TestListModelsGeminiIncludesSupportedGenerationMethods to
validate the mapping logic in model.go (SupportedEndpointTypes).

154-168: ⚡ Quick win

Consider using string type for dto.GeminiModel.Name instead of interface{}.

The type assertion on line 163 (name, ok := item.Name.(string)) confirms that Name is currently an interface{} field. Since model names from the Gemini API are always strings, changing this field to string would eliminate the runtime type assertion and provide compile-time type safety.

🤖 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 `@controller/model_list_test.go` around lines 154 - 168, The test's runtime
type assertion in decodeGeminiListModelsResponse shows dto.GeminiModel.Name is
declared as interface{}; change the Gemini model struct so Name is a string
(update dto.GeminiModel.Name from interface{} to string) to get compile-time
safety, remove the type assertion in decodeGeminiListModelsResponse, and then
update any call sites and JSON unmarshalling expectations that reference
dto.GeminiModel.Name to accept a string.
🤖 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.

Outside diff comments:
In `@controller/model.go`:
- Around line 248-257: The function getGeminiSupportedGenerationMethods
currently prioritizes prefix-based detection (normalizeGeminiModelID +
isGeminiVideoModel/isGeminiEmbeddingModel/isGeminiPredictModel) over endpoint
metadata; change it to first inspect openAIModel.SupportedEndpointTypes (and use
that to return the appropriate methods), and only if SupportedEndpointTypes is
empty or nil fall back to the existing prefix checks via normalizeGeminiModelID
and the isGemini* helpers; keep the same return values ("predictLongRunning",
"embedContent", "batchEmbedContents", "predict") and ensure the function still
returns nil when neither metadata nor prefix detection match.

---

Nitpick comments:
In `@controller/model_list_test.go`:
- Around line 277-316: Add test cases exercising the SupportedEndpointTypes →
generation methods mapping by extending
TestListModelsGeminiIncludesSupportedGenerationMethods (or adding a new test) to
create non-prefixed model entries (no "gemini-" prefix) and set their
SupportedEndpointTypes on the model records: one with SupportedEndpointTypes =
[]string{model.EndpointTypeGemini} and assert
geminiMethods(models["models/<name>"]) returns ["generateContent"], one with
SupportedEndpointTypes = []string{model.EndpointTypeEmbeddings} and assert it
returns ["embedContent","batchEmbedContents"], and one with
SupportedEndpointTypes = []string{} (or nil) and assert the fallback
["generateContent"] is returned; use the same DB setup,
model.InvalidatePricingCache/GetPricing flow and require.ElementsMatch
assertions as in TestListModelsGeminiIncludesSupportedGenerationMethods to
validate the mapping logic in model.go (SupportedEndpointTypes).
- Around line 154-168: The test's runtime type assertion in
decodeGeminiListModelsResponse shows dto.GeminiModel.Name is declared as
interface{}; change the Gemini model struct so Name is a string (update
dto.GeminiModel.Name from interface{} to string) to get compile-time safety,
remove the type assertion in decodeGeminiListModelsResponse, and then update any
call sites and JSON unmarshalling expectations that reference
dto.GeminiModel.Name to accept a string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c8a0462-598d-475f-a3ce-927d2aa5ae70

📥 Commits

Reviewing files that changed from the base of the PR and between dca82d4 and 0a354d6.

📒 Files selected for processing (2)
  • controller/model.go
  • controller/model_list_test.go

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-compatible /v1beta/models returns incomplete metadata (supportedGenerationMethods=null)

1 participant