Skip to content

feat: add MiniMax Chat node with M2.7 as default model#12924

Open
octo-patch wants to merge 4 commits intoComfy-Org:masterfrom
octo-patch:feature/add-minimax-chat-node
Open

feat: add MiniMax Chat node with M2.7 as default model#12924
octo-patch wants to merge 4 commits intoComfy-Org:masterfrom
octo-patch:feature/add-minimax-chat-node

Conversation

@octo-patch
Copy link
Copy Markdown

@octo-patch octo-patch commented Mar 13, 2026

Summary

Add a new MiniMax Chat node for text generation using MiniMax language models.

Changes

  • Add MiniMax Chat node with support for MiniMax-M2.7 (default), MiniMax-M2.7-highspeed, MiniMax-M2.5, and MiniMax-M2.5-highspeed models
  • Support system prompts, configurable temperature, and max tokens
  • Include pricing badge with per-model token cost estimates
  • MiniMax-M2.7 is the latest flagship model with enhanced reasoning and coding capabilities

Why

MiniMax provides high-quality language models through an OpenAI-compatible API. The M2.7 model is the latest flagship with improved performance.

Testing

  • Model enum validated: M2.7 models at front, M2.5 models retained for backward compatibility
  • Node schema correctly references M2.7 as default

API Node PR Checklist

Scope

  • Is API Node Change

Pricing & Billing

  • Need pricing update
  • No pricing update

If Need pricing update:

  • Metronome rate cards updated
  • Auto‑billing tests updated and passing

QA

  • QA done
  • QA not required

Comms

  • Informed Kosinkadink

Extend the existing MiniMax integration (currently video-only) with a new
MinimaxChatNode that supports text generation via MiniMax-M2.5 and
MiniMax-M2.5-highspeed language models. The node follows the same
ComfyExtension pattern used by OpenAI and Gemini chat nodes.

Changes:
- Add chat API models (request/response) to apis/minimax.py
- Add MinimaxChatNode with system prompt, temperature, and max_tokens support
- Register the new node in MinimaxExtension
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b900a9bf-98d7-44ab-99ac-ee070573fead

📥 Commits

Reviewing files that changed from the base of the PR and between 1ac73e8 and 8f84fde.

📒 Files selected for processing (1)
  • tests-unit/comfy_api_test/minimax_models_test.py

📝 Walkthrough

Walkthrough

Added a public node class MinimaxChatNode in comfy_api_nodes/nodes_minimax.py with define_schema exposing inputs: prompt (string, multiline), model (MiniMaxChatModel), optional system_prompt (string, multiline), max_tokens (int), and temperature (float); output: string. execute constructs MiniMax chat messages, issues a synchronous call to /proxy/minimax/chat/completions using MiniMaxChatRequest/MiniMaxChatResponse, and returns the first response content or raises if none. MinimaxExtension.get_node_list was updated to register MinimaxChatNode. Tests added for MiniMaxChatModel enum values and ordering.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a MiniMax Chat node with M2.7 as the default model, which is the primary objective of the PR.
Description check ✅ Passed The description is well-related to the changeset, covering the new MiniMax Chat node, supported models, features, and rationale for the changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@comfy_api_nodes/nodes_minimax.py`:
- Around line 551-553: The current code in nodes_minimax.py returns
IO.NodeOutput("No response generated by MiniMax model.") when response.choices
is empty, which masks API failures; instead, change the behavior in the function
that handles the MiniMax API response so that if response.choices is falsy you
raise an exception (e.g., RuntimeError or a custom exception) with a clear
message including any available response metadata (e.g., the raw response or
status) rather than returning IO.NodeOutput; update the branch that currently
checks response.choices and replace the fallback return with a raised error to
surface API anomalies consistently.
- Around line 524-548: The execute method forwards the model string unchecked;
validate that the provided model is a member of MiniMaxChatModel before sending
the request so invalid values fail fast. Add a local validation in
MiniMaxChatNode.execute (or the listed async execute) right after
validate_string(prompt...) that checks if model is one of MiniMaxChatModel.* (or
use MiniMaxChatModel(model) / an explicit membership check) and raise a clear
ValueError/IO.NodeError if not; only proceed to build messages and call sync_op
when the model is valid.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1736802c-61fd-461c-aa83-08868760e74c

📥 Commits

Reviewing files that changed from the base of the PR and between 4a8cf35 and acf25ee.

⛔ Files ignored due to path filters (1)
  • comfy_api_nodes/apis/minimax.py is excluded by !comfy_api_nodes/apis/**
📒 Files selected for processing (1)
  • comfy_api_nodes/nodes_minimax.py

- Validate `model` parameter against MiniMaxChatModel enum before
  forwarding to the API request, preventing invalid model strings.
- Raise RuntimeError instead of returning a fallback string when the
  API returns empty choices, surfacing failures consistently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@octo-patch
Copy link
Copy Markdown
Author

Thanks for the review feedback! I've pushed a fix (c01e019) addressing both issues:

  1. Model validation (line 544): The model parameter is now validated through the MiniMaxChatModel enum before being forwarded to the API request (MiniMaxChatModel(model).value). This ensures only recognized model identifiers are accepted and will raise a ValueError for any unexpected input.

  2. Empty choices handling (line 553): Replaced the silent fallback string with raise RuntimeError(...) so that an empty API response surfaces as an error rather than being silently swallowed.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@comfy_api_nodes/nodes_minimax.py`:
- Around line 539-552: The MiniMax chat request currently omits the
reasoning_split flag so message.content can contain <think> reasoning tags;
update the MiniMaxChatRequest constructed where sync_op is called (the call that
builds MiniMaxChatRequest with model=MiniMaxChatModel(model).value,
messages=messages, max_tokens=max_tokens, temperature=temperature) to include
reasoning_split=True so the API strips <think> markup before returning content
to be wrapped in IO.NodeOutput; ensure this change is applied to the
MiniMaxChatRequest used in the ApiEndpoint("/proxy/minimax/chat/completions",
method="POST") call that expects MiniMaxChatResponse.
- Around line 503-520: The price badge values for MiniMax in the IO.PriceBadge
expression are outdated; update the USD per-1K token arrays to match MiniMax API
pricing by replacing the current usd arrays in the expression for the two
branches: for the "highspeed" branch (when $contains(widgets.model,
"highspeed")) set usd to [0.0006, 0.0024], and for the default branch set usd to
[0.0003, 0.0012]; keep the surrounding structure (price_badge = IO.PriceBadge,
depends_on = IO.PriceBadgeDepends(widgets=["model"]), and the expr using $m :=
widgets.model and $contains) unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f7328424-41f5-4c4c-b817-edbd1d445259

📥 Commits

Reviewing files that changed from the base of the PR and between acf25ee and c01e019.

📒 Files selected for processing (1)
  • comfy_api_nodes/nodes_minimax.py

Comment on lines +503 to +520
price_badge=IO.PriceBadge(
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
expr="""
(
$m := widgets.model;
$contains($m, "highspeed") ? {
"type": "list_usd",
"usd": [0.00004, 0.0002],
"format": { "approximate": true, "separator": "-", "suffix": " per 1K tokens" }
}
: {
"type": "list_usd",
"usd": [0.0001, 0.0006],
"format": { "approximate": true, "separator": "-", "suffix": " per 1K tokens" }
}
)
""",
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's confirm the file exists and examine the relevant section
cat -n comfy_api_nodes/nodes_minimax.py | sed -n '500,525p'

Repository: Comfy-Org/ComfyUI

Length of output: 1113


🌐 Web query:

MiniMax M2.5 API pricing per token cost 2024 2025

💡 Result:

MiniMax M2.5 token pricing you’ll see published publicly is not a 2024/2025 price—MiniMax’s official pay‑as‑you‑go table listing MiniMax‑M2.5 appears in the current docs/pricing pages (live as of March 2026). [1]

Official MiniMax pay‑as‑you‑go (CNY)

Prices are shown as 元 / 1,000,000 tokens: [1]

  • Input: ¥2.1 / 1M tokens → ¥0.0000021 per token
  • Output: ¥8.4 / 1M tokens → ¥0.0000084 per token
  • (Also listed) Cache read: ¥0.21 / 1M; Cache write: ¥2.625 / 1M. [1]

Common USD quotes (third‑party trackers, for reference)

Artificial Analysis lists MiniMax‑M2.5 at: [2]

  • $0.30 / 1M input tokens (=$0.00000030/token)
  • $1.20 / 1M output tokens (=$0.00000120/token)

If you specifically need what MiniMax charged in 2024 or 2025, you’ll likely need an archived snapshot or a dated MiniMax announcement—because M2.5 pricing as such doesn’t appear to be a 2024/2025 item on the current official pages. [1]

Sources: [1] MiniMax Open Platform docs – Pay‑as‑you‑go pricing table (文本/按量计费) (platform.minimaxi.com) • [2] Artificial Analysis – MiniMax‑M2.5 pricing (artificialanalysis.ai)


🌐 Web query:

MiniMax M2.5 highspeed model pricing API cost

💡 Result:

MiniMax M2.5-highspeed API cost (Pay‑as‑you‑go)

From MiniMax’s pay‑as‑you‑go pricing table (prices in CNY per 1M tokens): Input ¥4.2 / 1M, Output ¥16.8 / 1M; cache read ¥0.21 / 1M, cache write ¥2.625 / 1M. [1]

Approximate USD equivalents (using ~¥6.88 per $1): input ~$0.61 / 1M, output ~$2.44 / 1M, cache read ~$0.03 / 1M, cache write ~$0.38 / 1M. [1][2]

(Reference) MiniMax M2.5 (non‑highspeed) PAYG

Input ¥2.1 / 1M (~$0.31), Output ¥8.4 / 1M (~$1.22). [1][2]

If you meant the Coding Plan (subscription, not per-token)

Plans that include MiniMax M2.5-highspeed are $40 / $80 / $150 per month (300 / 1000 / 2000 prompts per 5 hours). [3]

Sources: [1] MiniMax PAYG pricing table, [2] USD/CNY rate reference, [3] MiniMax Coding Plan pricing.


🏁 Script executed:

# Check if this node and price_badge are new additions
git log -1 --oneline comfy_api_nodes/nodes_minimax.py
git diff HEAD~1 comfy_api_nodes/nodes_minimax.py | head -100

Repository: Comfy-Org/ComfyUI

Length of output: 339


🏁 Script executed:

# Check the structure to confirm this is new code
git status comfy_api_nodes/nodes_minimax.py
git log --oneline -5 comfy_api_nodes/nodes_minimax.py

Repository: Comfy-Org/ComfyUI

Length of output: 201


Update price badge values to match current MiniMax API pricing.

The per-1K token amounts are materially below official rates. MiniMax's current pay-as-you-go pricing is $0.30/$1.20 per 1M tokens for M2.5 and $0.61/$2.44 per 1M tokens for M2.5-highspeed, which translates to $0.0003/$0.0012 and $0.0006/$0.0024 per 1K tokens respectively.

Suggested patch
                 (
                   $m := widgets.model;
                   $contains($m, "highspeed") ? {
                     "type": "list_usd",
-                    "usd": [0.00004, 0.0002],
+                    "usd": [0.0006, 0.0024],
                     "format": { "approximate": true, "separator": "-", "suffix": " per 1K tokens" }
                   }
                   : {
                     "type": "list_usd",
-                    "usd": [0.0001, 0.0006],
+                    "usd": [0.0003, 0.0012],
                     "format": { "approximate": true, "separator": "-", "suffix": " per 1K tokens" }
                   }
                 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_api_nodes/nodes_minimax.py` around lines 503 - 520, The price badge
values for MiniMax in the IO.PriceBadge expression are outdated; update the USD
per-1K token arrays to match MiniMax API pricing by replacing the current usd
arrays in the expression for the two branches: for the "highspeed" branch (when
$contains(widgets.model, "highspeed")) set usd to [0.0006, 0.0024], and for the
default branch set usd to [0.0003, 0.0012]; keep the surrounding structure
(price_badge = IO.PriceBadge, depends_on =
IO.PriceBadgeDepends(widgets=["model"]), and the expr using $m := widgets.model
and $contains) unchanged.

Comment on lines +539 to +552
response = await sync_op(
cls,
ApiEndpoint(path="/proxy/minimax/chat/completions", method="POST"),
response_model=MiniMaxChatResponse,
data=MiniMaxChatRequest(
model=MiniMaxChatModel(model).value,
messages=messages,
max_tokens=max_tokens,
temperature=temperature,
),
)

if response.choices:
return IO.NodeOutput(response.choices[0].message.content)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the MiniMax-related files
find . -name "*minimax*" -type f | head -20

Repository: Comfy-Org/ComfyUI

Length of output: 129


🏁 Script executed:

# Let's examine the MiniMax API models file
wc -l ./comfy_api_nodes/apis/minimax.py

Repository: Comfy-Org/ComfyUI

Length of output: 98


🏁 Script executed:

# And the nodes file
wc -l ./comfy_api_nodes/nodes_minimax.py

Repository: Comfy-Org/ComfyUI

Length of output: 99


🏁 Script executed:

# Read the MiniMaxChatRequest definition
cat -n ./comfy_api_nodes/apis/minimax.py | grep -A 50 "class MiniMaxChatRequest"

Repository: Comfy-Org/ComfyUI

Length of output: 1685


🏁 Script executed:

# Read the execute method from nodes_minimax.py around lines 539-552
sed -n '530,560p' ./comfy_api_nodes/nodes_minimax.py

Repository: Comfy-Org/ComfyUI

Length of output: 1157


🏁 Script executed:

# Check git status and history to see if this code is new
cd ./comfy_api_nodes && git log --oneline -20 -- nodes_minimax.py

Repository: Comfy-Org/ComfyUI

Length of output: 135


🏁 Script executed:

# Check if reasoning_split field was previously in the file
git log -p -- comfy_api_nodes/apis/minimax.py | grep -A 20 "reasoning_split" | head -30

Repository: Comfy-Org/ComfyUI

Length of output: 43


🏁 Script executed:

# Get more context about the MinimaxChatNode.execute method - find the full function
sed -n '520,560p' ./comfy_api_nodes/nodes_minimax.py

Repository: Comfy-Org/ComfyUI

Length of output: 1384


🏁 Script executed:

# Check the actual diff of the recent commit
git show c01e019 -- comfy_api_nodes/nodes_minimax.py | head -100

Repository: Comfy-Org/ComfyUI

Length of output: 3387


🏁 Script executed:

# Also check if there are any references to <think> or reasoning in the codebase
rg -i "think|reasoning" comfy_api_nodes/

Repository: Comfy-Org/ComfyUI

Length of output: 2830


🌐 Web query:

MiniMax API OpenAI compatible chat completions <think> markup reasoning_split parameter

💡 Result:

MiniMax’s OpenAI-compatible Chat Completions endpoint (/v1/chat/completions) can return interleaved thinking markup (e.g., <think>...</think>) in the assistant message.content for models like MiniMax-M2.5 / M2.1 / M2 (and their highspeed variants). MiniMax’s docs say that if you see <think> content in content, you must preserve it completely when storing/replaying conversation history. [1]

To avoid having <think> appear inside message.content, enable Interleaved Thinking compatible format by passing the extra parameter:

  • reasoning_split: true (aka reasoning_split=True in SDKs)

Then the model’s thinking is provided separately in message.reasoning_details (which also must be preserved completely), while message.content is the user-facing answer. [1][2]

Example (OpenAI SDK-style):

from openai import OpenAI

client = OpenAI(
  api_key="YOUR_MINIMAX_KEY",
  base_url="https://api.minimax.io/v1",
)

resp = client.chat.completions.create(
  model="MiniMax-M2.5",
  messages=[{"role":"user","content":"Explain X briefly."}],
  extra_body={"reasoning_split": True},
)

This “split thinking into reasoning_details via reasoning_split=True” behavior is explicitly documented by MiniMax. [1][2][3]

Sources: MiniMax OpenAI-compatible API docs (including <think> handling and reasoning_splitreasoning_details) [1], MiniMax “Tool Use & Interleaved Thinking” docs [2], MiniMax M2.5 release technical read (compatibility + reasoning_split) [3].

References: [1] (platform.minimax.io) [2] (platform.minimax.io) [3] (atoms.dev)

Citations:


🌐 Web query:

MiniMax M2.5 model reasoning content OpenAI API documentation

💡 Result:

MiniMax M2.5’s OpenAI-compatible Chat Completions endpoint does not use OpenAI’s documented “reasoning items” schema. Instead, MiniMax injects the model’s reasoning into the normal message.content as <think>…</think>, and MiniMax explicitly says you must preserve that <think> block verbatim in the conversation history (especially for multi-turn/tool use), because the OpenAI ChatCompletions format has no native place for it. [1], [2]

In OpenAI’s own API documentation, “reasoning content/state” is handled in the Responses API as dedicated reasoning items/streaming events (e.g., response.reasoning_text.*) and optionally encrypted reasoning you can request via include: ["reasoning.encrypted_content"] and pass back on later turns—this is separate from content and is not expressed as <think> tags. [3], [4], [5]

So: if you’re using MiniMax M2.5 via an OpenAI-compatible Chat Completions API, follow MiniMax’s docs for <think> handling; if you want OpenAI’s documented reasoning mechanism, use OpenAI’s Responses API reasoning items/encrypted content flow. [1], [3]

Sources:
[1] MiniMax “Compatible OpenAI API” docs (OpenAI-compatible endpoint; <think> in content)
[2] MiniMax “Tool Use & Interleaved Thinking” docs (why <think> is used in OpenAI-native format)
[3] OpenAI API Reference — Responses (reasoning items / reasoning.encrypted_content)
[4] OpenAI API Reference — Responses streaming (response.reasoning_text.*)
[5] OpenAI Cookbook — Responses API reasoning items (include=["reasoning.encrypted_content"])


Set reasoning_split=True to exclude <think> markup from node output.

MiniMax's OpenAI-compatible API includes <think> reasoning markup directly in message.content for MiniMax-M2.5 models by default. Without reasoning_split=True, the node will return raw reasoning tags to users. This requires adding the reasoning_split field to MiniMaxChatRequest and enabling it in the request. (platform.minimax.io)

Suggested fix
# comfy_api_nodes/apis/minimax.py
 class MiniMaxChatRequest(BaseModel):
     model: str = Field(..., description='ID of the model to use.')
     messages: list[MiniMaxChatMessage] = Field(..., description='A list of messages comprising the conversation.')
     max_tokens: Optional[int] = Field(None, description='The maximum number of tokens to generate.')
     temperature: Optional[float] = Field(
         None,
         description='Sampling temperature. Must be between 0 (exclusive) and 1 (inclusive).',
         gt=0.0,
         le=1.0,
     )
+    reasoning_split: Optional[bool] = Field(
+        None,
+        description='Return reasoning separately from content for the OpenAI-compatible MiniMax API.',
+    )

# comfy_api_nodes/nodes_minimax.py
         data=MiniMaxChatRequest(
             model=MiniMaxChatModel(model).value,
             messages=messages,
             max_tokens=max_tokens,
             temperature=temperature,
+            reasoning_split=True,
         ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_api_nodes/nodes_minimax.py` around lines 539 - 552, The MiniMax chat
request currently omits the reasoning_split flag so message.content can contain
<think> reasoning tags; update the MiniMaxChatRequest constructed where sync_op
is called (the call that builds MiniMaxChatRequest with
model=MiniMaxChatModel(model).value, messages=messages, max_tokens=max_tokens,
temperature=temperature) to include reasoning_split=True so the API strips
<think> markup before returning content to be wrapped in IO.NodeOutput; ensure
this change is applied to the MiniMaxChatRequest used in the
ApiEndpoint("/proxy/minimax/chat/completions", method="POST") call that expects
MiniMaxChatResponse.

@christian-byrne
Copy link
Copy Markdown
Contributor

We would need the actual proxy implementation in our backend for this to work right

- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to chat model list
- Set MiniMax-M2.7 as default model (replacing M2.5)
- Keep all previous models as available alternatives
@octo-patch octo-patch changed the title Add MiniMax Chat node for text generation feat: add MiniMax Chat node with M2.7 as default model Mar 18, 2026
- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to model list
- Set MiniMax-M2.7 as default model
- Keep all previous models as alternatives
- Add unit tests for model configuration
@octo-patch
Copy link
Copy Markdown
Author

Thanks for the feedback @christian-byrne! You're right - this PR only adds the frontend/node configuration. I'd be happy to implement the actual proxy backend as well if you can point me to the right location in the codebase for adding new provider backends. Alternatively, I can close this and resubmit once the backend implementation is included.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants