Skip to content
This repository was archived by the owner on Aug 13, 2026. It is now read-only.

feat: upgrade MiniMax default model to M3 - #6468

Open
octo-patch wants to merge 2 commits into
FlowiseAI:mainfrom
octo-patch:feature/upgrade-minimax-m3
Open

octo-patch wants to merge 2 commits into
FlowiseAI:mainfrom
octo-patch:feature/upgrade-minimax-m3

Conversation

@octo-patch

@octo-patch octo-patch commented Jun 2, 2026 •

Copy link
Copy Markdown

Reason: Refresh the existing MiniMax integration with current model parameters and China-region TTS endpoint parity.

Changes

  • Update MiniMax-M3 and MiniMax-M2.7 context, pricing, input modality, and thinking metadata.
  • Keep the model catalog aligned with the current supported model set.
  • Add credential-selectable global and China TTS endpoints.
  • Preserve the resolved max-token value when resetting the chat wrapper.
  • Add focused parameter and endpoint tests.

Checks

  • pnpm install --frozen-lockfile
  • ./.husky/pre-commit
  • pnpm --filter flowise-components exec jest --runInBand src/minimaxParameters.test.ts
  • pnpm --filter flowise-components build
  • git diff --check
  • git diff --cached --check

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for MiniMax services, including a new ChatMiniMax model node, MiniMax API credentials, and MiniMax Text-to-Speech (TTS) integration. Feedback on the changes highlights a critical bug in the TTS stream processing where the loop does not fully terminate and the stream reader is not cancelled on error or abort, leading to potential resource leaks. Additionally, the falsy checks for temperature and topP in the ChatMiniMax node should be updated to safe nullish checks to allow valid values of 0.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +159 to +211
const processMinimaxStream = async () => {
for (;;) {
if (abortController.signal.aborted) {
reader.cancel()
streamDestroyed = true
reject(new Error('TTS generation aborted'))
return
}

const { done, value } = await reader.read()
if (done) break

sseBuffer += decoder.decode(value, { stream: true })
const lines = sseBuffer.split('\n')
sseBuffer = lines.pop() || ''

for (const line of lines) {
const trimmedLine = line.trim()
if (!trimmedLine || trimmedLine.startsWith(':')) {
continue
}

if (trimmedLine.startsWith('data:')) {
const jsonStr = trimmedLine.slice(5).trim()
if (!jsonStr) continue

try {
const eventData = JSON.parse(jsonStr)

if (eventData.base_resp?.status_code !== 0) {
const errorMsg = eventData.base_resp?.status_msg || 'Unknown error'
reject(new Error(`MiniMax TTS error: ${errorMsg}`))
return
}

if (eventData.data?.audio) {
const audioChunk = Buffer.from(eventData.data.audio, 'hex')
onChunk(audioChunk)
}

if (eventData.data?.status === 2) {
break
}
} catch {
// Skip malformed JSON
}
}
}
}

onEnd()
resolve()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

There are two critical issues in processMinimaxStream:

  1. The break statement on line 200 only exits the inner for (const line of lines) loop. The outer for (;;) loop continues to run and call reader.read(), causing unnecessary processing and potential hangs.
  2. If an error occurs (status_code !== 0) or the stream is aborted, the stream reader is not properly cancelled, leading to resource/connection leaks.

Using a labeled loop (outerLoop) and ensuring reader.cancel() is called on all exit paths resolves these issues. Additionally, throwing an error when the API returns an invalid status code promotes fail-fast behavior.

const processMinimaxStream = async () => {
    try {
        outerLoop: for (;;) {
            if (abortController.signal.aborted) {
                await reader.cancel();
                streamDestroyed = true;
                reject(new Error("TTS generation aborted"));
                return;
            }

            const { done, value } = await reader.read();
            if (done) break;

            sseBuffer += decoder.decode(value, { stream: true });
            const lines = sseBuffer.split("\n");
            sseBuffer = lines.pop() || "";

            for (const line of lines) {
                const trimmedLine = line.trim();
                if (!trimmedLine || trimmedLine.startsWith(":")) {
                    continue;
                }

                if (trimmedLine.startsWith("data:")) {
                    const jsonStr = trimmedLine.slice(5).trim();
                    if (!jsonStr) continue;

                    try {
                        const eventData = JSON.parse(jsonStr);

                        if (eventData.base_resp?.status_code !== 0) {
                            const errorMsg = eventData.base_resp?.status_msg || "Unknown error";
                            await reader.cancel();
                            reject(new Error("MiniMax TTS error: " + errorMsg));
                            return;
                        }

                        if (eventData.data?.audio) {
                            const audioChunk = Buffer.from(eventData.data.audio, "hex");
                            onChunk(audioChunk);
                        }

                        if (eventData.data?.status === 2) {
                            await reader.cancel();
                            break outerLoop;
                        }
                    } catch {
                        // Skip malformed JSON
                    }
                }
            }
        }

        onEnd();
        resolve();
    } catch (err) {
        await reader.cancel().catch(() => {});
        reject(err);
    }
}
References
  1. When handling potentially invalid data from external sources (like an API response), prefer throwing an error for invalid input types rather than silently returning a default or empty value. This promotes fail-fast behavior.

Comment on lines +108 to +111
if (temperature) obj.temperature = parseFloat(temperature)
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
if (topP) obj.topP = parseFloat(topP)
if (cache) obj.cache = cache

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Checking if (temperature) can fail when temperature is resolved as the number 0 (which is falsy in JavaScript), preventing users from setting a deterministic temperature of 0. It is safer to check temperature != null && temperature !== '' to allow 0 as a valid value. Similarly, topP should be checked safely. Use loose equality (!= null) as a standard idiom for nullish checks.

Suggested change
if (temperature) obj.temperature = parseFloat(temperature)
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
if (topP) obj.topP = parseFloat(topP)
if (cache) obj.cache = cache
if (temperature != null && temperature !== '') obj.temperature = parseFloat(temperature)
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
if (topP != null && topP !== '') obj.topP = parseFloat(topP)
if (cache) obj.cache = cache
References
  1. In JavaScript/TypeScript, use loose equality (== null) as a standard idiom for a 'nullish' check that covers both null and undefined.

- Add ChatMiniMax node with FlowiseChatMiniMax integration
- Add MiniMaxApi credential definition
- Update models.json with MiniMax model list (M3, M2.7, M2.7-highspeed)
- Set MiniMax-M3 as the default model
- Add MiniMax TTS support in textToSpeech.ts
@octo-patch
octo-patch force-pushed the feature/upgrade-minimax-m3 branch from ec0c559 to a331603 Compare June 3, 2026 01:09

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant