feat(image_gen): add MiniMax provider plugin - #47660
Conversation
|
Duplicate of #25451 — both add a dedicated MiniMax |
5df660d to
5357580
Compare
Adds a hermes image_gen plugin for MiniMax (Anthropic transport)'s native image generation API. Why this exists: - hermes-agent built-in image_gen only supports OpenAI /v1/images/generations - MiniMax exposes a /v1/image_generation endpoint with its own request/response format, including GroupId header and per-model virtual IDs (image-01, image-01-live, etc.) - Without a native plugin, hermes cannot generate images via MiniMax This PR provides the same provider as NousResearch#47660 originally, but the content is now applied on top of the current upstream main (676236b) which was force-pushed since the PR was opened.
75bcbf5 to
5e9302a
Compare
|
Thanks for the comprehensive MiniMax implementation and its focused provider tests. This automated hermes-sweeper review is closing the PR under the standing
Please publish or continue this as a standalone MiniMax image-generation plugin repository, then share it in Automated hermes-sweeper review; closed as not planned under standing policy Closed as not-planned per standing maintainer policy ( |
What does this PR do?
Adds
MiniMaxImageGenProvider— a first-classimage_genplugin for the MiniMax image generation API athttps://api.minimax.io/v1/image_generation. The MiniMax image backend is currently a special case in the image_generate tool, hardcoded alongside the OpenAI-shaped path. This PR moves it onto the samePluginContext.register_image_gen_providerpath that the other 5 backends (fal,krea,openai,openai-codex,xai) already use, so it benefits from the same picker UX, setup wizard, and error-response contract.Why a separate plugin: MiniMax's image API is not OpenAI-compatible —
POST /v1/images/generationsreturns 404. The native/v1/image_generationendpoint uses a different URL, a different response shape (datais a dict{image_urls, b64_json}, not a list), and an optionalGroupIdquery parameter. A dedicated plugin keeps the OpenAI-shaped providers (fal, openai, openai-codex, xai) on their shared code path, while MiniMax handles its own auth + parsing + GroupId quirk in isolation. The picker gets a real model list, the setup wizard surfacesMINIMAX_API_KEYautomatically, and the gateway gets uniformsuccess_response/error_responseregardless of which provider ran.Related Issue
None — this is a feature addition.
Type of Change
Changes Made
plugins/image_gen/minimax/__init__.py:MiniMaxImageGenProviderimplementing theImageGenProviderABC. Three virtual model IDs (minimax-image-01,minimax-image-01-live,minimax-image-01-square) backed by theimage-01/image-01-liveMiniMax models. Auth viaAuthorization: Bearer $MINIMAX_API_KEY; optional?GroupId=$MINIMAX_GROUP_IDquery string for accounts on group-scoped billing. Downloads the signed CDN URL to$HERMES_HOME/cache/images/at tool-completion time (mirrors the xAI pattern inplugins/image_gen/xai/__init__.py) so the gateway'ssend_photonever hits the 30-minute TTL. Returnssuccess_response/error_responseper the base class contract.plugins/image_gen/minimax/plugin.yaml: plugin manifest withkind: backend,requires_env: MINIMAX_API_KEY,optional_env: MINIMAX_GROUP_ID. Author:Vality.tests/plugins/image_gen/test_minimax_provider.py: 31 unit tests + 1 opt-in live test. Coversis_available(with/without key),list_models(3 IDs in expected order),default_model,get_setup_schema(env vars + required:false for GroupId),_resolve_model(env override > config > default),_resolve_aspect(-squarealias forces 1:1),generate()input validation (empty/whitespace prompt, missing key, invalidn, invalidresponse_format), request shape (URL with/without GroupId query, payloadmodelfield for each virtual ID,-squarealias overrides aspect_ratio,seed/prompt_optimizer/aigc_watermarkpassthroughs), success path (URL response cached to disk, b64 response cached to disk, URL cache failure falls back to bare URL), error paths (401, 404 with GroupId message, empty data dict, response with neither url nor b64, timeout, connection error), and registration (register()wires the provider into the registry correctly).How to Test
End-to-end via the picker (after installing the plugin):
Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass (145 of 145 image_gen tests pass; 11 unrelated pre-existing failures intests/tools/test_image_generation.py::TestManagedGatewayErrorTranslation,tests/plugins/memory/test_hindsight_provider.py::TestConfig, andtests/plugins/video_gen/test_fal_plugin.py::TestFamilyRoutingare present onmainwithout my changes — verified by stashing and re-running)49dd91d68Documentation & Housekeeping
docs/, docstrings) — or N/A (module docstring covers the auth quirks and endpoint shape; no user-facing docs to update)cli-config.yaml.exampleif I added/changed config keys — or N/A (no new config keys;MINIMAX_API_KEYis surfaced via the existingget_setup_schema()flow)CONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/Asave_url_image'srequestsusage, which matches the other 5 providers)success_response/error_response— used by all other providers)