feat: Convert gemini request - #1484
Conversation
WalkthroughThis change introduces a standardized conversion interface for Gemini chat requests across all relay adaptors, adds comprehensive Gemini↔OpenAI conversion logic, and updates all relevant type references to use the Changes
Sequence Diagram(s)Gemini Request Conversion and Relay FlowsequenceDiagram
participant Client
participant RelayHandler
participant Adaptor
participant Service
participant Upstream
Client->>RelayHandler: Send GeminiChatRequest
RelayHandler->>Adaptor: ConvertGeminiRequest(ctx, info, GeminiChatRequest)
Adaptor->>RelayHandler: ConvertedRequest / error
RelayHandler->>Service: (optional) GeminiToOpenAIRequest(ConvertedRequest)
Service->>RelayHandler: OpenAIRequest
RelayHandler->>Upstream: Send OpenAIRequest or GeminiRequest
Upstream-->>RelayHandler: Response (OpenAI/Gemini)
RelayHandler->>Service: (optional) ResponseOpenAI2Gemini(Response)
Service->>RelayHandler: GeminiChatResponse
RelayHandler->>Client: GeminiChatResponse
OpenAI Relay Streaming Gemini SupportsequenceDiagram
participant Upstream
participant OpenAIHelper
participant Service
participant Client
Upstream-->>OpenAIHelper: Streamed OpenAI response chunk
OpenAIHelper->>Service: StreamResponseOpenAI2Gemini(chunk)
Service-->>OpenAIHelper: GeminiChatResponse
OpenAIHelper->>Client: Send GeminiChatResponse as custom event
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
✨ Finishing Touches
🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
relay/channel/claude_code/adaptor.go (1)
28-31: LGTM! Proper interface implementation stub.The method correctly implements the interface signature and returns an appropriate "not implemented" error. The TODO comment helps track future implementation needs.
Do you want me to track this TODO in an issue or help implement the Gemini to Claude conversion logic?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (36)
dto/gemini.go(3 hunks)relay/channel/adapter.go(1 hunks)relay/channel/ali/adaptor.go(1 hunks)relay/channel/aws/adaptor.go(1 hunks)relay/channel/baidu/adaptor.go(1 hunks)relay/channel/baidu_v2/adaptor.go(2 hunks)relay/channel/claude/adaptor.go(1 hunks)relay/channel/claude_code/adaptor.go(1 hunks)relay/channel/cloudflare/adaptor.go(1 hunks)relay/channel/cohere/adaptor.go(1 hunks)relay/channel/coze/adaptor.go(1 hunks)relay/channel/deepseek/adaptor.go(1 hunks)relay/channel/dify/adaptor.go(1 hunks)relay/channel/gemini/adaptor.go(3 hunks)relay/channel/gemini/relay-gemini-native.go(2 hunks)relay/channel/gemini/relay-gemini.go(23 hunks)relay/channel/jimeng/adaptor.go(1 hunks)relay/channel/jina/adaptor.go(1 hunks)relay/channel/mistral/adaptor.go(1 hunks)relay/channel/mokaai/adaptor.go(1 hunks)relay/channel/ollama/adaptor.go(1 hunks)relay/channel/openai/adaptor.go(2 hunks)relay/channel/openai/helper.go(4 hunks)relay/channel/openai/relay-openai.go(1 hunks)relay/channel/palm/adaptor.go(1 hunks)relay/channel/perplexity/adaptor.go(1 hunks)relay/channel/siliconflow/adaptor.go(1 hunks)relay/channel/tencent/adaptor.go(1 hunks)relay/channel/vertex/adaptor.go(1 hunks)relay/channel/volcengine/adaptor.go(1 hunks)relay/channel/xai/adaptor.go(1 hunks)relay/channel/xunfei/adaptor.go(1 hunks)relay/channel/zhipu/adaptor.go(1 hunks)relay/channel/zhipu_4v/adaptor.go(1 hunks)relay/gemini_handler.go(5 hunks)service/convert.go(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
📚 Learning: in relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the maxout...
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
Applied to files:
relay/channel/gemini/relay-gemini-native.gorelay/channel/zhipu_4v/adaptor.gorelay/channel/perplexity/adaptor.gorelay/channel/baidu_v2/adaptor.gorelay/channel/ollama/adaptor.gorelay/channel/openai/adaptor.gorelay/channel/openai/relay-openai.gorelay/channel/adapter.gorelay/gemini_handler.gorelay/channel/openai/helper.gorelay/channel/gemini/relay-gemini.go
📚 Learning: gin.context implements context.context interface since gin v1.8.0, providing the methods deadline(),...
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Applied to files:
relay/channel/jimeng/adaptor.gorelay/gemini_handler.go
🧬 Code Graph Analysis (21)
relay/channel/gemini/relay-gemini-native.go (1)
dto/gemini.go (1)
GeminiChatResponse(165-169)
relay/channel/cloudflare/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/claude_code/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/ali/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/xai/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/xunfei/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/cohere/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/volcengine/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
dto/gemini.go (1)
dto/openai_response.go (1)
FunctionResponse(128-134)
relay/channel/zhipu_4v/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/claude/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/perplexity/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/jimeng/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/baidu/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/ollama/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/deepseek/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/gemini/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (7)
GeminiChatRequest(8-14)GeminiImageRequest(185-188)GeminiImageInstance(190-192)GeminiImageParameters(194-198)GeminiEmbeddingRequest(212-217)GeminiChatContent(117-120)GeminiPart(79-88)
relay/channel/openai/relay-openai.go (4)
relay/common/relay_info.go (1)
RelayFormatGemini(39-39)service/convert.go (1)
ResponseOpenAI2Gemini(621-700)common/json.go (1)
Marshal(20-22)types/error.go (2)
NewError(176-188)ErrorCodeBadResponseBody(66-66)
relay/channel/vertex/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/mokaai/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
relay/channel/mistral/adaptor.go (3)
relay/channel/adapter.go (1)
Adaptor(13-30)relay/common/relay_info.go (1)
RelayInfo(62-113)dto/gemini.go (1)
GeminiChatRequest(8-14)
🔇 Additional comments (63)
dto/gemini.go (3)
1-1: LGTM! Package reorganization improves centralization.The package name change from
geminitodtocentralizes Gemini data structures and aligns with the broader refactoring effort.
59-62: Good namespace clarity with renamed struct.Renaming
FunctionResponsetoGeminiFunctionResponseprevents naming conflicts and provides better clarity when used alongside OpenAI types.
84-84: Consistent field type update.The field type update to use
*GeminiFunctionResponsemaintains consistency with the struct rename.relay/channel/gemini/relay-gemini-native.go (2)
31-31: LGTM! Consistent use of centralized DTO types.The update to use
dto.GeminiChatResponsealigns with the centralization of Gemini types in the dto package.
74-74: Consistent type usage in streaming handler.The streaming handler correctly uses the same centralized
dto.GeminiChatResponsetype, maintaining consistency across both handlers.relay/channel/claude/adaptor.go (1)
27-30: LGTM! Proper interface compliance.The stub implementation correctly satisfies the interface requirement with an appropriate "not implemented" error and TODO comment for future development.
relay/channel/adapter.go (1)
29-29: LGTM! Clean interface extension.The
ConvertGeminiRequestmethod addition follows established patterns with consistent signature design and appropriate parameter types. The positioning afterConvertClaudeRequestmaintains logical grouping.relay/channel/vertex/adaptor.go (1)
47-49: LGTM - Appropriate pass-through implementation for Vertex AI.The implementation correctly returns the Gemini request unchanged, which is appropriate since Vertex AI (Google's platform) natively supports Gemini requests and doesn't require format conversion.
relay/channel/aws/adaptor.go (1)
25-28: LGTM - Proper placeholder implementation.The "not implemented" stub is appropriate for the AWS adaptor since it doesn't support Gemini request conversion. The use of anonymous parameters is correct for unused parameters.
relay/channel/xai/adaptor.go (1)
22-25: LGTM - Consistent stub implementation.The "not implemented" placeholder is appropriate for the XAI adaptor. The implementation follows the established pattern with proper error handling and anonymous parameters.
relay/channel/xunfei/adaptor.go (1)
20-23: LGTM - Appropriate stub implementation.The "not implemented" placeholder follows the established pattern in this file and is appropriate since the Xunfei adaptor doesn't support Gemini request conversion.
relay/channel/baidu/adaptor.go (1)
21-24: LGTM - Consistent placeholder implementation.The "not implemented" stub is appropriate for the Baidu adaptor and follows the established pattern across channel adaptors. The implementation correctly uses anonymous parameters and consistent error messaging.
relay/channel/volcengine/adaptor.go (1)
26-29: LGTM! Consistent placeholder implementation.The
ConvertGeminiRequestmethod follows the standard interface signature and returns an appropriate "not implemented" error. This placeholder implementation is consistent with the pattern used across other channel adaptors in this PR.relay/channel/coze/adaptor.go (1)
21-24: LGTM! Consistent placeholder implementation.The
ConvertGeminiRequestmethod correctly implements the interface signature and returns an appropriate "not implemented" error, maintaining consistency with other channel adaptors.relay/channel/ollama/adaptor.go (1)
20-23: LGTM! Consistent placeholder with clear implementation path.The
ConvertGeminiRequestmethod follows the standard interface signature. When implementing this method in the future, consider following the pattern used inConvertClaudeRequest(lines 25-35) where the request is first converted via the OpenAI adaptor and then transformed to Ollama format.relay/channel/cohere/adaptor.go (1)
20-23: LGTM! Consistent placeholder implementation.The
ConvertGeminiRequestmethod correctly implements the interface signature and handles the unimplemented state appropriately with a clear error message.relay/channel/zhipu/adaptor.go (1)
19-22: LGTM! Consistent placeholder implementation.The
ConvertGeminiRequestmethod maintains the standard interface signature and error handling pattern used across all channel adaptors in this PR. This establishes a solid foundation for future Gemini request conversion implementations.relay/channel/zhipu_4v/adaptor.go (1)
21-24: LGTM: Proper interface compliance stub.The stub implementation correctly follows the new interface contract from
relay/channel/adapter.go. The "not implemented" error is appropriate for future implementation.relay/channel/jina/adaptor.go (1)
22-25: LGTM: Consistent stub implementation.The implementation matches the interface requirements and follows the same pattern as other channel adaptors.
relay/channel/dify/adaptor.go (1)
27-30: LGTM: Standard interface stub implementation.The method correctly implements the interface contract with an appropriate placeholder error message.
relay/channel/ali/adaptor.go (1)
21-24: LGTM: Proper stub implementation.The method correctly implements the new interface requirement with consistent error handling.
relay/channel/tencent/adaptor.go (1)
28-31: LGTM: Consistent interface implementation across all adaptors.This stub implementation matches the pattern used across all channel adaptors in this PR, properly implementing the new
ConvertGeminiRequestinterface method. The coordinated addition of this method across multiple adaptors demonstrates good interface evolution practices.relay/channel/cloudflare/adaptor.go (1)
21-24: LGTM! Proper interface implementation with placeholder.The
ConvertGeminiRequestmethod correctly implements the interface requirement with an appropriate "not implemented" stub. The method signature matches the interface definition and the TODO comment clearly indicates future implementation is needed.relay/channel/perplexity/adaptor.go (1)
20-23: LGTM! Consistent interface implementation.The method properly implements the
ConvertGeminiRequestinterface requirement with an appropriate placeholder implementation. The error message and TODO comment clearly indicate the method's current state.relay/channel/siliconflow/adaptor.go (1)
21-24: LGTM! Proper placeholder implementation.The
ConvertGeminiRequestmethod correctly implements the interface requirement with appropriate error handling for the unimplemented functionality. The method signature and error message are consistent with the interface specification.relay/channel/deepseek/adaptor.go (1)
22-25: LGTM! Consistent interface compliance.The method properly implements the
ConvertGeminiRequestinterface requirement with appropriate placeholder behavior. The implementation is consistent with other stub methods in the codebase.relay/channel/mokaai/adaptor.go (1)
21-24: LGTM! Consistent with interface extension pattern.The
ConvertGeminiRequestmethod correctly implements the interface requirement with an appropriate placeholder implementation. This maintains consistency with the systematic interface extension across all channel adaptors.relay/channel/palm/adaptor.go (1)
20-23: LGTM! Placeholder method follows the established pattern.The
ConvertGeminiRequestmethod correctly implements the interface with appropriate error handling. This follows the same pattern as other unimplemented methods in this adaptor (ConvertAudioRequest, ConvertImageRequest, etc.).relay/channel/mistral/adaptor.go (1)
19-22: LGTM! Consistent stub implementation.The
ConvertGeminiRequestmethod correctly implements the interface requirement with appropriate error handling, maintaining consistency with other unimplemented methods in this adaptor.relay/channel/jimeng/adaptor.go (2)
15-16: Minor import organization improvement.Moving the gin import to the end of the import block improves code organization.
22-25: LGTM! Consistent placeholder implementation.The
ConvertGeminiRequestmethod follows the established pattern for unimplemented methods in this adaptor, correctly implementing the interface requirement.relay/channel/openai/relay-openai.go (1)
226-232: Excellent! Gemini format support integration.The implementation correctly adds Gemini format support to the OpenAI relay handler, following the established pattern used for Claude format conversion. The error handling and response marshaling are properly implemented.
relay/channel/baidu_v2/adaptor.go (2)
21-24: LGTM! Consistent interface implementation.The
ConvertGeminiRequestmethod correctly implements the interface requirement with appropriate error handling, following the established pattern for unimplemented methods.
51-59: Code formatting improvement.The indentation and spacing corrections improve code readability while maintaining the existing logic for API key parsing and header setup.
relay/channel/openai/adaptor.go (2)
37-44: LGTM!The implementation correctly converts Gemini requests to OpenAI format using the service layer conversion function, then delegates to the existing OpenAI request conversion logic.
76-77: LGTM!The URL routing correctly handles the Gemini format alongside Claude format, both using the same OpenAI-compatible endpoint path.
relay/channel/gemini/adaptor.go (2)
23-25: LGTM!The passthrough implementation is appropriate for the Gemini adaptor since it natively handles Gemini-formatted requests.
58-69: LGTM!The type updates correctly use the centralized
dtopackage types for Gemini data structures, improving code organization and consistency.Also applies to: 145-153
relay/gemini_handler.go (2)
23-24: LGTM!The type updates correctly use the centralized
dto.GeminiChatRequesttype throughout the handler functions.Also applies to: 47-47, 64-64, 81-81
205-210: LGTM!The conversion step is properly integrated with appropriate error handling. This allows different channel adaptors to transform Gemini requests according to their specific requirements.
relay/channel/openai/helper.go (4)
5-6: LGTM!The new imports are necessary for error creation and HTTP flushing in the Gemini handling code.
27-28: LGTM!The Gemini format routing is correctly added to the switch statement, following the established pattern.
49-77: LGTM!The implementation correctly handles Gemini format streaming responses with proper error handling, nil checks for empty chunks, and HTTP flushing.
224-253: LGTM!The final response handling for Gemini format is properly implemented, converting and sending the last stream data as a custom event with appropriate error handling and flushing.
service/convert.go (4)
452-595: LGTM!The
GeminiToOpenAIRequestconversion is comprehensive and handles all aspects of the translation including messages, roles, media content, tool calls, generation parameters, and system instructions. The bounds checking for stop sequences (limiting to 4) is a good defensive measure.
597-618: LGTM!The helper functions for role conversion and text extraction are well-implemented with appropriate default cases.
621-700: LGTM!The
ResponseOpenAI2Geminifunction correctly converts OpenAI responses to Gemini format with proper handling of finish reasons, tool calls, and usage metadata.
703-800: LGTM!The streaming conversion function properly handles empty initial chunks by returning nil and correctly transforms streaming responses with appropriate finish reason mapping and content handling.
relay/channel/gemini/relay-gemini.go (15)
84-84: LGTM: Function signature updated to use dto package types.The function signature correctly uses the relocated
dto.GeminiChatRequesttype, consistent with the refactoring objectives.
96-131: LGTM: ThinkingConfig assignments updated to use dto types.All ThinkingConfig instantiations correctly use the relocated
dto.GeminiThinkingConfigtype, maintaining the existing logic while using the centralized dto package.
140-150: LGTM: Function signature and request instantiation updated to dto types.The function correctly returns
*dto.GeminiChatRequestand instantiates the request using the appropriate dto package types (dto.GeminiChatRequest,dto.GeminiChatContent,dto.GeminiChatGenerationConfig).
161-167: LGTM: Safety settings updated to use dto types.Safety settings correctly use
dto.GeminiChatSafetySettingstype, maintaining the existing safety configuration logic.
201-214: LGTM: Tool assignments updated to use dto types.All tool assignments (
CodeExecution,GoogleSearch,FunctionDeclarations) correctly use thedto.GeminiChatTooltype from the dto package.
241-279: LGTM: Content processing updated to use dto types.Content and parts processing correctly uses dto package types (
dto.GeminiChatContent,dto.GeminiPart,dto.GeminiFunctionResponse), maintaining the existing conversion logic.
293-380: LGTM: Part instantiations updated to dto types across all content types.All part instantiations correctly use dto package types:
dto.GeminiPartfor all part typesdto.FunctionCallfor function callsdto.GeminiInlineDatafor media contentThe conversion logic for text, images, files, and audio content remains intact.
395-401: LGTM: System instructions updated to use dto types.System instructions correctly use
dto.GeminiChatContentanddto.GeminiParttypes, maintaining the existing system message processing logic.
639-639: LGTM: Function parameter updated to dto type.The function parameter correctly uses
*dto.GeminiPartfrom the dto package, maintaining consistency with the type migration.
661-661: LGTM: Function parameter updated to dto response type.The function parameter correctly uses
*dto.GeminiChatResponsefrom the dto package, maintaining consistency with the response type migration.
728-728: LGTM: Stream response function parameter updated to dto type.The function parameter correctly uses
*dto.GeminiChatResponsefrom the dto package, maintaining consistency with the streaming response handling.
833-833: LGTM: Stream handler uses dto response type.The variable declaration correctly uses
dto.GeminiChatResponsefor unmarshaling the streaming response.
916-916: LGTM: Chat handler uses dto response type.The variable declaration correctly uses
dto.GeminiChatResponsefor unmarshaling the chat completion response.
962-962: LGTM: Embedding handler uses dto response type.The variable declaration correctly uses
dto.GeminiEmbeddingResponsefor unmarshaling the embedding response.
1008-1008: LGTM: Image handler uses dto response type.The variable declaration correctly uses
dto.GeminiImageResponsefor unmarshaling the image generation response.
…uest feat: Convert gemini request
relay/channel/gemini/dto.go到dto/gemini.goSummary by CodeRabbit
New Features
Improvements
Bug Fixes