aecbb9a2ee
* feat: add MiniMax as a chat completion provider Add MiniMax (https://www.minimax.io) as a first-class chat completion provider. MiniMax already has TTS integration in SillyTavern; this extends support to LLM chat completions via their OpenAI-compatible API. Supported models: - MiniMax-M2.5 (default) — 204K context - MiniMax-M2.5-highspeed — same capability, faster inference Key implementation details: - Reuses existing SECRET_KEYS.MINIMAX (shared with TTS) - API endpoint: https://api.minimax.io/v1 - Temperature clamped to (0.0, 1.0] as required by MiniMax API - Returns hardcoded model list since MiniMax doesn't expose /v1/models - Full UI integration: model selector, sampler parameters, streaming Co-Authored-By: octo-patch <octo-patch@users.noreply.github.com> * feat: upgrade MiniMax default model to M2.7 - 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 * feat: independent request function, vision support, temp clamping for MiniMax - Extract sendMinimaxRequest() following Chutes pattern (PR #4844) with function calling and JSON Schema structured output support - Clamp temperature to (0.01, 1.0] on backend; limit frontend UI max to 1.0 - Enable image inlining for MiniMax M2.7 model - Add MiniMax to slash-commands model selector and tokenizer mapping - Add minimax_model to default preset * feat: add VLM-based vision support for MiniMax M2.7 M2.7 does not natively accept image input. When images are detected in messages, pre-process them via the MiniMax VLM endpoint (/v1/coding_plan/vlm) to convert images to text descriptions before sending to the chat completions API. Uses the same API key. * feat: add M2-her model to MiniMax provider M2-her is MiniMax's dialogue/roleplay-optimized model with 64K context and 2048 max completion tokens. Text-only (no vision). * feat: add MiniMax China endpoint (minimaxi.com) support Add endpoint selector (Global/China) for MiniMax, mirroring the SiliconFlow pattern. Users can now choose between api.minimax.io (international) and api.minimaxi.com (China domestic). * fix: merge consecutive same-role messages for MiniMax MiniMax API rejects consecutive messages with the same role with error 'invalid chat setting (2013)'. Merge them before sending. * review: address PR feedback on MiniMax provider Backend (src/endpoints/backends/chat-completions.js): - Drop the entire MiniMax VLM image-preprocessing path; vision is no longer advertised for this provider, so M2.7 messages now go straight to /chat/completions without a separate VLM round-trip. - Drop the json_schema -> response_format mapping (MiniMax does not document structured-output support; relying on it was speculative). - Drop the backend temperature clamp; the same clamp now lives in the frontend so the wire payload matches what the user sees. - Drop the MINIMAX branch in /status that returned a hard-coded model list; the frontend hardcodes the same list and bypasses /status via noValidateSources, so the round-trip was wasted. - Add a streaming Transform + non-streaming helper that move <think>...</think> blocks from delta.content / message.content to reasoning_content. MiniMax M2.x emit chain-of-thought inline in content; without this transform the raw <think> tags leak into the rendered chat. Includes a state machine that holds back partial marker bytes so a marker split across SSE chunks is still detected. Frontend: - public/scripts/openai.js: add MINIMAX to noValidateSources so the key is accepted without a /models call; remove the dead saveModelList branch; clamp temperature to (0.0, 1.0] in createGenerationParameters. - public/scripts/reasoning.js: add MINIMAX to the non-streaming reasoning_content extraction case (the backend transform now produces this field for MiniMax responses). - public/scripts/slash-commands.js: add MINIMAX to the /api enum and add a MiniMax case to /api-url so users can switch endpoint by command. - public/scripts/custom-request.js: pass minimax_endpoint through the override-payload merge alongside the other per-source endpoint fields. - public/scripts/tokenizers.js: stop returning openai_model (which was always a MiniMax model id and thus an unknown tokenizer); fall back to gpt-3.5-turbo for a coarse but functional estimate. - public/scripts/tool-calling.js: add MINIMAX to supportedSources so function-calling settings are exposed. - public/index.html: drop the "-- Connect to the API --" placeholder option from the model select (the model list is hardcoded and always populated); remove minimax from the vision data-source attributes on the inline-media controls. - public/img/minimax.svg: replace the multicolor brand SVG with a single-color currentColor version that matches the other provider icons in the connect panel. * review: drop backend <think> parsing, defer to frontend Per reviewer feedback: SillyTavern's reasoningHandler / reasoning_auto_parse setting already extracts <think>...</think> blocks on the client side, so the backend doesn't need to rewrite MiniMax responses. Removes the SSE Transform, the non-streaming helper, and the corresponding case in reasoning.js. * fix: remove isImageInliningSupported declaration for MINIMAX * fix: remove MINIMAX from stream reasoning parsing * fix: add to autoconnect logic * fix: add missing MINIMAX models from docs * fix: freq. and pres. pen aren't supported for MINIMAX * fix: use clamp function for adjusting temperature * fix: pass minimax_endpoint from connection profile to ChatCompletionService * fix: update supported APIs in slash command documentation * fix: replace bespoke merge with standard MERGE_TOOLS processing * fix: add data-i18n attributes for headers --------- Co-authored-by: octo-patch <octo-patch@users.noreply.github.com> Co-authored-by: octo-patch <octo-patch@github.com> Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
246 lines
7.6 KiB
JSON
246 lines
7.6 KiB
JSON
{
|
|
"chat_completion_source": "openai",
|
|
"openai_model": "gpt-4-turbo",
|
|
"claude_model": "claude-sonnet-4-5",
|
|
"openrouter_model": "OR_Website",
|
|
"openrouter_use_fallback": false,
|
|
"openrouter_group_models": false,
|
|
"openrouter_sort_models": "alphabetically",
|
|
"ai21_model": "jamba-large",
|
|
"mistralai_model": "mistral-large-latest",
|
|
"chutes_model": "deepseek-ai/DeepSeek-V3-0324",
|
|
"chutes_sort_models": "alphabetically",
|
|
"minimax_model": "MiniMax-M2.7",
|
|
"minimax_endpoint": "global",
|
|
"electronhub_model": "gpt-4o-mini",
|
|
"electronhub_sort_models": "alphabetically",
|
|
"electronhub_group_models": false,
|
|
"custom_model": "",
|
|
"custom_url": "",
|
|
"custom_include_body": "",
|
|
"custom_exclude_body": "",
|
|
"custom_include_headers": "",
|
|
"google_model": "gemini-2.5-pro",
|
|
"vertexai_model": "gemini-2.5-pro",
|
|
"temperature": 1,
|
|
"frequency_penalty": 0,
|
|
"presence_penalty": 0,
|
|
"top_p": 1,
|
|
"top_k": 0,
|
|
"top_a": 0,
|
|
"min_p": 0,
|
|
"repetition_penalty": 1,
|
|
"openai_max_context": 4095,
|
|
"openai_max_tokens": 300,
|
|
"names_behavior": 0,
|
|
"send_if_empty": "",
|
|
"impersonation_prompt": "[Write your next reply from the point of view of {{user}}, using the chat history so far as a guideline for the writing style of {{user}}. Don't write as {{char}} or system. Don't describe actions of {{char}}.]",
|
|
"new_chat_prompt": "[Start a new Chat]",
|
|
"new_group_chat_prompt": "[Start a new group chat. Group members: {{group}}]",
|
|
"new_example_chat_prompt": "[Example Chat]",
|
|
"continue_nudge_prompt": "[Continue your last message without repeating its original content.]",
|
|
"bias_preset_selected": "Default (none)",
|
|
"reverse_proxy": "",
|
|
"proxy_password": "",
|
|
"max_context_unlocked": false,
|
|
"wi_format": "{0}",
|
|
"scenario_format": "{{scenario}}",
|
|
"personality_format": "{{personality}}",
|
|
"group_nudge_prompt": "[Write the next reply only as {{char}}.]",
|
|
"stream_openai": true,
|
|
"prompts": [
|
|
{
|
|
"name": "Main Prompt",
|
|
"system_prompt": true,
|
|
"role": "system",
|
|
"content": "Write {{char}}'s next reply in a fictional chat between {{char}} and {{user}}.",
|
|
"identifier": "main"
|
|
},
|
|
{
|
|
"name": "Auxiliary Prompt",
|
|
"system_prompt": true,
|
|
"role": "system",
|
|
"content": "",
|
|
"identifier": "nsfw"
|
|
},
|
|
{
|
|
"identifier": "dialogueExamples",
|
|
"name": "Chat Examples",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"name": "Post-History Instructions",
|
|
"system_prompt": true,
|
|
"role": "system",
|
|
"content": "",
|
|
"identifier": "jailbreak"
|
|
},
|
|
{
|
|
"identifier": "chatHistory",
|
|
"name": "Chat History",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"identifier": "worldInfoAfter",
|
|
"name": "World Info (after)",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"identifier": "worldInfoBefore",
|
|
"name": "World Info (before)",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"identifier": "enhanceDefinitions",
|
|
"role": "system",
|
|
"name": "Enhance Definitions",
|
|
"content": "If you have more knowledge of {{char}}, add to the character's lore and personality to enhance them but keep the Character Sheet's definitions absolute.",
|
|
"system_prompt": true,
|
|
"marker": false
|
|
},
|
|
{
|
|
"identifier": "charDescription",
|
|
"name": "Char Description",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"identifier": "charPersonality",
|
|
"name": "Char Personality",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"identifier": "scenario",
|
|
"name": "Scenario",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
},
|
|
{
|
|
"identifier": "personaDescription",
|
|
"name": "Persona Description",
|
|
"system_prompt": true,
|
|
"marker": true
|
|
}
|
|
],
|
|
"prompt_order": [
|
|
{
|
|
"character_id": 100000,
|
|
"order": [
|
|
{
|
|
"identifier": "main",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "worldInfoBefore",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "charDescription",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "charPersonality",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "scenario",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "enhanceDefinitions",
|
|
"enabled": false
|
|
},
|
|
{
|
|
"identifier": "nsfw",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "worldInfoAfter",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "dialogueExamples",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "chatHistory",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "jailbreak",
|
|
"enabled": true
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"character_id": 100001,
|
|
"order": [
|
|
{
|
|
"identifier": "main",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "worldInfoBefore",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "personaDescription",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "charDescription",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "charPersonality",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "scenario",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "enhanceDefinitions",
|
|
"enabled": false
|
|
},
|
|
{
|
|
"identifier": "nsfw",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "worldInfoAfter",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "dialogueExamples",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "chatHistory",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"identifier": "jailbreak",
|
|
"enabled": true
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"show_external_models": false,
|
|
"assistant_prefill": "",
|
|
"assistant_impersonation": "",
|
|
"use_sysprompt": false,
|
|
"squash_system_messages": false,
|
|
"media_inlining": true,
|
|
"bypass_status_check": false,
|
|
"continue_prefill": false,
|
|
"continue_postfix": " ",
|
|
"seed": -1,
|
|
"n": 1
|
|
}
|