Skip to content

feat(models): add MiniMax H3-Image and Highspeed - #10240

Open
renningg wants to merge 3 commits into
invoke-ai:mainfrom
renningg:feat/minimax-h3-image
Open

renningg wants to merge 3 commits into
invoke-ai:mainfrom
renningg:feat/minimax-h3-image

Conversation

@renningg

@renningg renningg commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add MiniMax's new H3-Image and H3-Image Highspeed models to Invoke as hosted generators. Both support text-to-image and reference-guided edits in Compose and Canvas, and are available through the MiniMax Image Generation workflow node.

The live results were impressive, especially on reference edits. The two-reference example below keeps the conservatory's framing and places the red folding bicycle from a second image into the scene. I'd like to bring that capability to Invoke's existing external image workflow.

  • Register both variants with one MiniMax API key and an optional regional base URL.
  • Send explicit width and height to the generation or edit endpoint, save results to the Gallery, and record the provider model and request ID.
  • Support up to 16 reference inputs. A Canvas edit uses one slot for the composite.

QA Instructions

  1. Save a MiniMax key under Models → API Keys → MiniMax.
  2. In Compose, select MiniMax H3-Image or MiniMax H3-Image Highspeed, choose a size, enter a prompt, and click Invoke.
  3. Use the Gallery output as a reference, change the prompt, and run an edit. Add a second reference to verify that the two images are passed in order.

Nine jobs completed against a live MiniMax endpoint from Compose. They covered text-to-image, one- and two-reference edits, 1024 × 1024, 2720 × 1536, 1536 × 2720, and 4096 × 4096. Both Highspeed runs recorded the expected model ID in the output metadata.

Live Compose screenshots

Text-to-image Two-reference edit
Cliffside conservatory generated from a text prompt Red folding bicycle placed into the conservatory scene using two reference images
4K square generation Highspeed portrait edit
Compass and rope still life generated at 4096 by 4096 Landscape funicular photo reframed as a portrait with Highspeed

Each live case has screenshots of the Compose setup and the Gallery result.

Case Output size Setup Result
H3-Image · Cliffside conservatory 1024 × 1024 Setup Result
H3-Image · Folding bicycle 1024 × 1024 Setup Result
H3-Image · Blue-hour edit 1024 × 1024 Setup Result
H3-Image · Two-reference edit 1024 × 1024 Setup Result
H3-Image · Landscape generation 2720 × 1536 Setup Result
H3-Image · Square still life 4096 × 4096 Setup Result
H3-Image · Portrait reframing 1536 × 2720 Setup Result
Highspeed · Landscape generation 2720 × 1536 Setup Result
Highspeed · Portrait reframing 1536 × 2720 Setup Result

Completed queue for the four square test cases

  • 527 Python provider and configuration tests, 725 generation and Canvas tests, 5 legacy graph tests, and 2 API type generation tests passed. Python Ruff, frontend lint and architecture checks, and shared API formatting passed.
  • The full local release check stopped at two macOS shortcut-label assertions. Both also fail on clean upstream 5b776e3f8b. The later release gates were not reached in that run. Legacy TypeScript diagnostics also match the baseline.

Review

The adapter validates request limits locally and uses inline image responses. The integration allows output dimensions up to 4096 pixels per side. Shared external-model settings and Canvas preflight behavior remain follow-up items. For example, the current Render panel can show Steps and CFG even when the provider does not use them.

Compatibility / Rollout

The PR includes the regenerated OpenAPI and TypeScript contracts. Saving a MiniMax key registers both starter models. Existing local MiniMax H3 video models continue to use their local weights.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Meaningful regression coverage added / updated where needed; obsolete tests/code removed
  • Persisted-state and API changes include required migrations / compatibility validation
  • Relevant performance/efficiency opportunities considered; material claims have evidence
  • Material review findings resolved and relevant checks rerun
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

Register standard and Highspeed starter models and route generation and reference edits to MiniMax. Add credential configuration, request validation, and matching API contracts.
Expose MiniMax credentials in Model Manager and compile hosted image generation and Canvas edits. Cover model routing, dimensions, and reference limits.
Document credentials, regional endpoints, image sizes, and reference-guided edits.
@github-actions github-actions Bot added api python PRs that change python files invocations PRs that change invocations backend PRs that change backend files services PRs that change app services frontend PRs that change frontend files python-tests PRs that change python tests docs PRs that change docs labels Nov 11, 2026
@Pfannkuchensack Pfannkuchensack self-assigned this Nov 11, 2026

@Pfannkuchensack Pfannkuchensack left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, this is a clean provider. I checked the adapter against MiniMax's H3 reference pages (international and China). Endpoints, Bearer auth, model IDs, size as an exact WIDTHxHEIGHT with no aspect_ratio/area, n 1–10, the 32,000-character trimmed prompt, the 655,360–20,000,000 px area and 1:3–3:1 ratio, the b64_json 80M px JPEG limit, the reference limits (1–16, 128–8192 px, 4:1, 64 MiB body) and the init-first ordering all match. https://api.minimax.cn is the documented China host, so the docs page is correct. Not retrying 429 and allow_redirects=False are the right calls for a billed, non-idempotent request.

One medium point, then some smaller ones.

Medium

1. Users never see why MiniMax refused a request (providers/minimax.py:77-79, :99-100)

Every non-2xx response becomes MiniMax image request failed (HTTP 402). MiniMax's error body says what went wrong and what to do: 1008/2053 insufficient balance, 2068 plan tier doesn't include the model, 1026 prompt failed the safety check, 1004/2049 invalid key, 1002/2056 rate or plan-window limit, 2013 invalid parameters. A user with no credit and a user with a blocked prompt get the same bare status code.

The same thing happens on HTTP 200. When some items carry error (for example 1027, output failed the safety check), they are dropped without a word: a user who asked for 4 images gets 2 and no explanation. When every item fails, the message is only "contained no inline images". seedream.py keeps these as provider_metadata["partial_failures"] and puts the first item message into the error.

I understand the sanitizing is deliberate. The test asserts it. But the structured fields are provider-authored and hold neither the key nor the prompt. Suggestion: read error.type and the numeric code in error.message, and map the known codes to fixed Invoke messages (fall back to the HTTP status). Do the same for per-item error.code, and record partial failures the way Seedream does. That keeps the sanitizing and makes the failures actionable. Please add a test for a 402, a 422 and a partial 1027.

Low

2. MiniMax rewrites every prompt, and Invoke doesn't say so or keep the rewrite (minimax.py:46-53, :102-107)

disable_prompt_enhanced defaults to false on /v1/images/generations, and edits always enhance. So every request runs on a rewritten prompt, while Invoke's metadata records only the original. Please either put data[].revised_prompt into provider_metadata or mention the rewriting in minimax.mdx. Exposing disable_prompt_enhanced as a provider option is a natural follow-up.

3. The 4096 px per-side cap isn't from the API, and it leaves the 20M check unreachable (minimax.py:119-125, starter_models/external.py max_image_size, baseGenerationPolicies.ts minimaxArea)

The API accepts any WxH up to 20,000,000 px at up to 3:1. That covers its own 4K presets such as 5472×3072 and 4736×3552. With both sides capped at 4096, the largest area is 16.7M px, so the upper bound of the area check is dead in the backend, in webv2 and in the minimaxArea message. If the cap is deliberate (an Invoke-side limit?), please say why in a comment and drop the dead upper bound. Otherwise raise max_image_size and let the area check do the work.

4. The client timeout equals the server's maximum wait (minimax.py:23, :69)

The docs say the server waits up to 600 s and bills images even after the client disconnects. With timeout=600 (connect and read), a slow 4K request can time out on our side just before the response arrives. The user is charged and the images are lost. Something like timeout=(10, 660) avoids that.

5. Validation duplicated across three places, plus two dead branches

  • MiniMaxImageGenerationInvocation.invoke repeats the 16-input check from _validate_request. It's the only provider node that overrides invoke. Rejecting before the images load is a fair reason, but the limit now lives in the provider, the node, the starter capabilities and webv2. MINIMAX_MAX_INPUT_IMAGES is also provider-specific but sits in the shared external_generation_common.py. Please consider one source, for example the model's capabilities.max_reference_images.
  • _validate_request checks request.mode not in ("txt2img", "img2img") and img2img without inputs. The service already rejects both (external_generation_default.py:107 for modes, :142 for input_image_required_for), so these branches can't be reached.

6. Canvas preflight lets a 16-reference edit through (baseGenerationPolicies.ts:2991-3003)

For a provider that supports txt2img, getGenerateInvocationIssues always validates the Canvas in txt2img mode. So 16 active references pass the form check, and the edit then throws "supports at most 15 reference images" at compile time. You mention Canvas preflight as a follow-up, which is fine. Noting it so it isn't lost.

Nits

  • webv2/scripts/mock-backend.mjs:407: EXTERNAL_PROVIDER_IDS doesn't list minimax, so the mock backend's credential flow is missing the new card.
  • Output is fixed to JPEG at the default quality of 95. That's reasonable given the PNG limit of 20M px, but repeated Canvas edits stack compression. output_compression: 100 would be a cheap improvement.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api backend PRs that change backend files docs PRs that change docs frontend PRs that change frontend files invocations PRs that change invocations python PRs that change python files python-tests PRs that change python tests services PRs that change app services

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants