Add MiniMax image generation support#358
Conversation
|
Warning Review limit reached
More reviews will be available in 48 minutes and 52 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR integrates MiniMax image generation (models image-01 / image-01-live), adds per-group and default image-model settings, expands the generate_image tool with MiniMax parameters and routing, implements MiniMax request/response handling and validation, updates capability discovery, adds a DB column, updates docs/help/messages, and adds tests. ChangesMiniMax Image Generation Support
Sequence DiagramsequenceDiagram
participant User
participant GeneralLLMController
participant ModelCapabilityService
participant ImageGenerationToolService
participant MiniMaxGateway
participant Storage
User->>GeneralLLMController: "选择生图模型" / numeric reply
GeneralLLMController->>ModelCapabilityService: GetImageGenerationModels()
ModelCapabilityService-->>GeneralLLMController: model list
GeneralLLMController->>ImageGenerationToolService: SetGroupModelNameAsync / GenerateImage request
ImageGenerationToolService->>MiniMaxGateway: POST /v1/image_generation (if MiniMax)
MiniMaxGateway-->>ImageGenerationToolService: response JSON
ImageGenerationToolService->>Storage: SaveImageAsync (persist image)
ImageGenerationToolService-->>GeneralLLMController: result message
GeneralLLMController-->>User: reply with images/status
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
PR Check ReportSummary
Test Results
Code Quality
Test Artifacts
LinksThis report is auto-generated by GitHub Actions |
There was a problem hiding this comment.
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 `@TelegramSearchBot/Service/Tools/ImageGenerationToolService.cs`:
- Around line 237-257: The MiniMax branch still accepts an outputFormat but
never uses it, causing downstream SaveImageAsync to misname payloads; update the
IsMiniMaxImageGeneration/RequestMiniMaxImagesAsync flow to either
propagate/outputFormat into the MiniMax request body or fail fast: when
useMiniMax is true and the provided outputFormat is not supported (e.g., not
provider-default), immediately return or throw an argument/validation error
before calling RequestMiniMaxImagesAsync; alternatively modify
RequestMiniMaxImagesAsync to accept the outputFormat parameter and ensure the
response/meta includes the actual format so SaveImageAsync uses the correct
extension (refer to IsMiniMaxImageGeneration, RequestMiniMaxImagesAsync,
BuildMiniMaxImageGenerationEndpoint, and SaveImageAsync to locate and implement
the change).
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2f23c56c-43f6-4054-bed1-f8c9cd330fab
📒 Files selected for processing (7)
Docs/Bot_Commands_User_Guide.mdDocs/README_MCP.mdREADME.mdTelegramSearchBot.LLM/Service/AI/LLM/OpenAIService.csTelegramSearchBot.Test/Service/Tools/ImageGenerationToolServiceTests.csTelegramSearchBot/Service/Manage/EditLLMConfService.csTelegramSearchBot/Service/Tools/ImageGenerationToolService.cs
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 (2)
TelegramSearchBot/Service/Tools/ImageGenerationToolService.cs (2)
839-840:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winHandle
data:URLs inimage_base64arrays.The single-value base64 path already strips
data:image/...;base64,prefixes, but array entries skip that normalization and will fail inConvert.FromBase64String. Reuse the same parsing here so compatible gateways can return either raw base64 or data URLs.🩹 Proposed fix
foreach (var base64 in GetStringArrayValues(obj, "image_base64")) { - yield return new ImageResponseData(base64, null, null); + if (TryParseImageDataUrl(base64, out _, out var contentType, out var strippedBase64)) { + yield return new ImageResponseData(strippedBase64, null, contentType); + } else { + yield return new ImageResponseData(base64, null, null); + } }🤖 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 `@TelegramSearchBot/Service/Tools/ImageGenerationToolService.cs` around lines 839 - 840, The array branch yields ImageResponseData for each string from GetStringArrayValues("image_base64") but doesn't strip leading "data:image/...;base64," prefixes like the single-value path does, causing Convert.FromBase64String to fail; update the loop in ImageGenerationToolService (the block that creates new ImageResponseData(base64, ...)) to normalize each entry by detecting and removing the "data:" URI prefix (e.g. "data:*;base64,") before creating ImageResponseData so both raw base64 and data URLs are supported—reuse the same parsing/normalization logic used for the single-value image_base64 handling to ensure consistent behavior.
222-223:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPrefer
base64as the default MiniMax response format.Defaulting MiniMax to
urlmakes the bot download provider-supplied URLs server-side. With custom gateways enabled, that turns a misconfigured or compromised gateway into arbitrary outbound fetches by default.base64is the safer default and still leavesurlavailable when explicitly requested.🔒 Proposed mitigation
- private const string DefaultMiniMaxResponseFormat = "url"; + private const string DefaultMiniMaxResponseFormat = "base64"; ... - [BuiltInParameter("MiniMax response format: url or base64. Defaults to url. Leave empty for OpenAI-compatible models.", IsRequired = false)] string minimaxResponseFormat = DefaultMiniMaxResponseFormat, + [BuiltInParameter("MiniMax response format: base64 or url. Defaults to base64. Leave empty for OpenAI-compatible models.", IsRequired = false)] string minimaxResponseFormat = DefaultMiniMaxResponseFormat,Also applies to: 269-270, 299-301
🤖 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 `@TelegramSearchBot/Service/Tools/ImageGenerationToolService.cs` around lines 222 - 223, Change the default MiniMax response format from "url" to the safer "base64" by updating the DefaultMiniMaxResponseFormat constant in ImageGenerationToolService (replace "url" with "base64") and update any other places in this file that set or assume the default MiniMax response format (the other occurrences referenced in your review) so they use "base64" by default while leaving "url" available when explicitly requested; ensure any code that parses or validates the format still accepts both "base64" and "url".
🤖 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 `@TelegramSearchBot/Controller/AI/LLM/GeneralLLMController.cs`:
- Around line 346-370: LoadImageGenerationModelOptionsAsync currently collapses
entries by ModelName and only presents a channel summary, and
SaveImageGenerationModelSelectionAsync persists only the ModelName — change the
option to carry a unique identifier per channel (e.g., composite key like
"{ModelName}#{LLMChannel.Id}/{Provider}" or a separate ChannelId field) by
updating ImageGenerationModelSelectionOption to include that identifier, adjust
LoadImageGenerationModelOptionsAsync to emit one option per unique
channel-identifier (or include the identifier alongside the displayed summary),
and change SaveImageGenerationModelSelectionAsync to persist the identifier(s)
(using GetImageGenerationModelSelectionKey for the key) instead of only
modelName so downstream routing can unambiguously select the correct
gateway/provider; keep the same 50-item and 10-minute limits while ensuring any
UI-facing label remains the human-readable ModelName/channel summary.
---
Outside diff comments:
In `@TelegramSearchBot/Service/Tools/ImageGenerationToolService.cs`:
- Around line 839-840: The array branch yields ImageResponseData for each string
from GetStringArrayValues("image_base64") but doesn't strip leading
"data:image/...;base64," prefixes like the single-value path does, causing
Convert.FromBase64String to fail; update the loop in ImageGenerationToolService
(the block that creates new ImageResponseData(base64, ...)) to normalize each
entry by detecting and removing the "data:" URI prefix (e.g. "data:*;base64,")
before creating ImageResponseData so both raw base64 and data URLs are
supported—reuse the same parsing/normalization logic used for the single-value
image_base64 handling to ensure consistent behavior.
- Around line 222-223: Change the default MiniMax response format from "url" to
the safer "base64" by updating the DefaultMiniMaxResponseFormat constant in
ImageGenerationToolService (replace "url" with "base64") and update any other
places in this file that set or assume the default MiniMax response format (the
other occurrences referenced in your review) so they use "base64" by default
while leaving "url" available when explicitly requested; ensure any code that
parses or validates the format still accepts both "base64" and "url".
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 00efefd4-5322-43b1-b60d-c4327f6ddecd
📒 Files selected for processing (19)
Docs/Bot_Commands_User_Guide.mdDocs/README_MCP.mdREADME.mdTelegramSearchBot.Common/Model/AI/ModelWithCapabilities.csTelegramSearchBot.Database/Migrations/20260531041305_AddGroupImageGenerationModel.Designer.csTelegramSearchBot.Database/Migrations/20260531041305_AddGroupImageGenerationModel.csTelegramSearchBot.Database/Migrations/DataDbContextModelSnapshot.csTelegramSearchBot.Database/Model/Data/GroupSettings.csTelegramSearchBot.LLM.Test/Service/AI/LLM/ModelCapabilityServiceTests.csTelegramSearchBot.LLM.Test/Service/AI/LLM/ModelWithCapabilitiesTests.csTelegramSearchBot.LLM/Interface/IModelCapabilityService.csTelegramSearchBot.LLM/Service/AI/LLM/ModelCapabilityService.csTelegramSearchBot.LLM/Service/AI/LLM/OpenAIResponsesService.csTelegramSearchBot.LLM/Service/AI/LLM/OpenAIService.csTelegramSearchBot.Test/Service/Tools/ImageGenerationToolServiceTests.csTelegramSearchBot/Controller/AI/LLM/GeneralLLMController.csTelegramSearchBot/Controller/Help/HelpController.csTelegramSearchBot/Service/Manage/EditLLMConfService.csTelegramSearchBot/Service/Tools/ImageGenerationToolService.cs
✅ Files skipped from review due to trivial changes (6)
- TelegramSearchBot.Database/Migrations/20260531041305_AddGroupImageGenerationModel.cs
- TelegramSearchBot.Database/Migrations/DataDbContextModelSnapshot.cs
- TelegramSearchBot.Database/Migrations/20260531041305_AddGroupImageGenerationModel.Designer.cs
- README.md
- Docs/README_MCP.md
- Docs/Bot_Commands_User_Guide.md
🚧 Files skipped from review as they are similar to previous changes (1)
- TelegramSearchBot.Test/Service/Tools/ImageGenerationToolServiceTests.cs
| private async Task<List<ImageGenerationModelSelectionOption>> LoadImageGenerationModelOptionsAsync() { | ||
| var models = await _modelCapabilityService.GetImageGenerationModels(); | ||
| return models | ||
| .Where(x => !string.IsNullOrWhiteSpace(x.ModelName) && x.LLMChannel != null) | ||
| .GroupBy(x => x.ModelName.Trim(), StringComparer.OrdinalIgnoreCase) | ||
| .Select(group => { | ||
| var channels = group | ||
| .Select(x => $"{x.LLMChannel.Name}#{x.LLMChannel.Id}/{x.LLMChannel.Provider}") | ||
| .Distinct(StringComparer.OrdinalIgnoreCase) | ||
| .OrderBy(x => x) | ||
| .ToList(); | ||
| var channelSummary = channels.Count <= 3 | ||
| ? string.Join(", ", channels) | ||
| : $"{string.Join(", ", channels.Take(3))} 等 {channels.Count} 个渠道"; | ||
| return new ImageGenerationModelSelectionOption(group.Key, channelSummary); | ||
| }) | ||
| .OrderBy(x => x.ModelName, StringComparer.OrdinalIgnoreCase) | ||
| .ToList(); | ||
| } | ||
|
|
||
| private async Task SaveImageGenerationModelSelectionAsync(long chatId, long userId, List<ImageGenerationModelSelectionOption> options) { | ||
| var db = _connectionMultiplexer.GetDatabase(); | ||
| var key = GetImageGenerationModelSelectionKey(chatId, userId); | ||
| var modelNames = options.Take(50).Select(x => x.ModelName); | ||
| await db.StringSetAsync(key, string.Join('\n', modelNames), TimeSpan.FromMinutes(10)); |
There was a problem hiding this comment.
Persist the selected channel, not just the model name.
LoadImageGenerationModelOptionsAsync() merges every duplicate into one option keyed only by ModelName, and SaveImageGenerationModelSelectionAsync() stores only that name. If the same model exists on multiple channels, the admin cannot actually choose which gateway/provider backs the setting even though the UI shows per-channel summaries. Store a channel identifier (or another unique composite key) through the pending-selection flow and group settings so downstream routing is unambiguous.
🤖 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 `@TelegramSearchBot/Controller/AI/LLM/GeneralLLMController.cs` around lines 346
- 370, LoadImageGenerationModelOptionsAsync currently collapses entries by
ModelName and only presents a channel summary, and
SaveImageGenerationModelSelectionAsync persists only the ModelName — change the
option to carry a unique identifier per channel (e.g., composite key like
"{ModelName}#{LLMChannel.Id}/{Provider}" or a separate ChannelId field) by
updating ImageGenerationModelSelectionOption to include that identifier, adjust
LoadImageGenerationModelOptionsAsync to emit one option per unique
channel-identifier (or include the identifier alongside the displayed summary),
and change SaveImageGenerationModelSelectionAsync to persist the identifier(s)
(using GetImageGenerationModelSelectionKey for the key) instead of only
modelName so downstream routing can unambiguously select the correct
gateway/provider; keep the same 50-item and 10-minute limits while ensuring any
UI-facing label remains the human-readable ModelName/channel summary.
|
Addressed the MiniMax response-format review items in cb7b512: MiniMax now defaults to base64 and image_base64 array entries can include data URLs. I am intentionally keeping image model selection scoped to model name only: this matches the existing group LLM model setting behavior, while concrete channel/API key/gateway selection remains in the existing ChannelsWithModel routing by channel priority/concurrency. Binding a group setting to a channel id would introduce a second routing model. |
Summary
generate_imagetool to call MiniMax/v1/image_generationforimage-01andimage-01-livewhile keeping OpenAI-compatible image generation unchanged.Validation
dotnet build TelegramSearchBot.sln --configuration Release --no-restoredotnet test TelegramSearchBot.sln --configuration Release --no-buildSummary by CodeRabbit
New Features
Documentation