Revert "Gemini Image系列支持图像编辑" - #2338
Conversation
WalkthroughThis PR systematically removes special-case handling for image-related request modes across the relay system. It eliminates dedicated multipart/form-data processing for images-edits, removes public base64 extraction utilities, simplifies Gemini image content handling to a targeted "gemini-3-pro-image" model branch, and refactors internal file access to use accessor methods instead of direct struct fields. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
relay/channel/gemini/adaptor.go (1)
146-175: Address inconsistent JSON error handling in the image generation flow.The code adds support for
gemini-3-pro-imagemodels by convertingImageRequestto a chat-styleGeneralOpenAIRequestwith Google-specific generation config. One concern:Error handling: Line 172 silently ignores JSON marshaling errors with
extraBody, _ = json.Marshal(extraBody). The codebase consistently handles errors fromjson.Marshalin other locations. Update to:- chatRequest.ExtraBody, _ = json.Marshal(extraBody) + extraBodyBytes, err := json.Marshal(extraBody) + if err != nil { + return nil, fmt.Errorf("failed to marshal extraBody: %w", err) + } + chatRequest.ExtraBody = extraBodyBytesThe model names ("nano-banana", "gemini-2.5-flash-image") are valid and documented in
setting/model_setting/gemini.go. The ImageSize clearing workaround is properly commented and targets the specific models requiring the fix.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
relay/channel/api_request.go(0 hunks)relay/channel/gemini/adaptor.go(1 hunks)relay/channel/gemini/relay-gemini.go(2 hunks)relay/common/relay_utils.go(0 hunks)relay/helper/valid_request.go(0 hunks)
💤 Files with no reviewable changes (3)
- relay/helper/valid_request.go
- relay/channel/api_request.go
- relay/common/relay_utils.go
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: RedwindA
Repo: QuantumNous/new-api PR: 1537
File: relay/gemini_handler.go:330-342
Timestamp: 2025-08-08T17:12:43.157Z
Learning: In the new-api repository, the `GeminiEmbeddingHandler` function in `relay/gemini_handler.go` is designed specifically for native Gemini embedding requests and therefore does not require the `ConvertGeminiRequest` step that is used in the chat handler. The embedding requests are already in the native Gemini format and don't need conversion.
📚 Learning: 2025-08-08T17:12:43.157Z
Learnt from: RedwindA
Repo: QuantumNous/new-api PR: 1537
File: relay/gemini_handler.go:330-342
Timestamp: 2025-08-08T17:12:43.157Z
Learning: In the new-api repository, the `GeminiEmbeddingHandler` function in `relay/gemini_handler.go` is designed specifically for native Gemini embedding requests and therefore does not require the `ConvertGeminiRequest` step that is used in the chat handler. The embedding requests are already in the native Gemini format and don't need conversion.
Applied to files:
relay/channel/gemini/relay-gemini.gorelay/channel/gemini/adaptor.go
📚 Learning: 2025-08-05T17:14:17.246Z
Learnt from: neotf
Repo: QuantumNous/new-api PR: 1511
File: setting/ratio_setting/model_ratio.go:118-123
Timestamp: 2025-08-05T17:14:17.246Z
Learning: Claude models handle "-thinking" variants differently from Gemini models. For Claude models, only the base model (without "-thinking") gets an entry in defaultModelRatio map. The "-thinking" variants rely on the Claude relay handler stripping the suffix using strings.TrimSuffix(textRequest.Model, "-thinking") before looking up the ratio, so they automatically use the base model's ratio.
Applied to files:
relay/channel/gemini/adaptor.go
📚 Learning: 2025-08-04T14:36:34.528Z
Learnt from: antecanis8
Repo: QuantumNous/new-api PR: 1500
File: relay/channel/gemini/adaptor.go:0-0
Timestamp: 2025-08-04T14:36:34.528Z
Learning: In the Gemini API batchEmbedContents endpoint, each request item in the "requests" array should include its own "model" field, as shown in the official documentation at https://ai.google.dev/api/embeddings?hl=zh-cn#method:-models.batchembedcontents. The model field is not a top-level parameter.
Applied to files:
relay/channel/gemini/adaptor.go
🧬 Code graph analysis (2)
relay/channel/gemini/relay-gemini.go (3)
dto/openai_request.go (1)
GeneralOpenAIRequest(26-98)dto/gemini.go (1)
GeminiChatRequest(14-23)service/image.go (1)
DecodeBase64FileData(43-66)
relay/channel/gemini/adaptor.go (2)
dto/openai_request.go (2)
GeneralOpenAIRequest(26-98)Message(282-293)model/model_meta.go (1)
Model(23-44)
🔇 Additional comments (1)
relay/channel/gemini/relay-gemini.go (1)
185-185: LGTM: Simplified function signature removes image editing complexity.The removal of the variadic
base64Dataparameter simplifies the function interface and aligns with this PR's goal of removing special-case image editing handling. This change makes the conversion flow more straightforward.
| if part.GetFile().FileId != "" { | ||
| return nil, fmt.Errorf("only base64 file is supported in gemini") | ||
| } | ||
| format, base64String, err := service.DecodeBase64FileData(file.FileData) | ||
| format, base64String, err := service.DecodeBase64FileData(part.GetFile().FileData) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find GetFile() method definition
rg -n "func.*GetFile\(\)" --type=go -A5 | head -30Repository: QuantumNous/new-api
Length of output: 414
🏁 Script executed:
#!/bin/bash
# Check GetFile usage patterns and any nil checks
rg -n -B2 -A2 "GetFile\(\)" --type=go | head -60Repository: QuantumNous/new-api
Length of output: 1250
🏁 Script executed:
#!/bin/bash
# Look for proto definitions related to File or Content
fd -e proto -e pb.go | xargs grep -l "GetFile" 2>/dev/null | head -10Repository: QuantumNous/new-api
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Get the full GetFile() implementation
sed -n '339,360p' dto/openai_request.goRepository: QuantumNous/new-api
Length of output: 678
Add nil check before calling GetFile() accessor methods.
The GetFile() method (defined in dto/openai_request.go:339) explicitly returns nil if m.File is nil or fails type assertions. At lines 467 and 470, the code directly calls GetFile().FileId and GetFile().FileData without null safety checks, creating a panic risk. Ensure the result is assigned to a variable and checked for nil before dereferencing, following the pattern used elsewhere (e.g., dto/openai_request.go:163).
🤖 Prompt for AI Agents
In relay/channel/gemini/relay-gemini.go around lines 467 to 470, the code calls
part.GetFile().FileId and part.GetFile().FileData directly which can panic
because GetFile() may return nil; assign the result of part.GetFile() to a local
variable, check it for nil before accessing FileId/FileData, and return an
appropriate error (or handle the nil case) if the file is nil; follow the
existing pattern used elsewhere (e.g., dto/openai_request.go:163) to safe-guard
the dereferences.
|
这个 feature 还是需要的,请问有无计划加回来 |
|
…emini-image-edit Revert "Gemini Image系列支持图像编辑"
Reverts #2321
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.