From 86fe78c73f523e95d129a1f7f1668366b6a14817 Mon Sep 17 00:00:00 2001 From: Zhichang Yu Date: Thu, 7 May 2026 11:54:49 +0800 Subject: [PATCH] feat(llm): add MiniMax GroupId header support (#14610) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add MiniMax provider GroupId query parameter support in `LiteLLMBase` - Extract `group_id` from key configuration in `__init__` - Append `GroupId` as query parameter to `api_base` in `_construct_complete_args` ## Why this change is needed MiniMax provides an OpenAI-compatible API endpoint (`/v1/chat/completions`), but `GroupId` is a MiniMax-specific account identifier required for billing and rate limiting - it is not part of the OpenAI standard. Looking at LiteLLM's `MinimaxChatConfig`: - `get_complete_url()` only constructs the base URL (e.g., `https://api.minimaxi.com/v1/chat/completions`) - LiteLLM does **not** automatically inject `GroupId` into requests - This must be handled by the caller (ragflow's chat_model.py) The implementation appends `GroupId` as a query parameter to `api_base`: ```python api_base = completion_args.get("api_base", self.base_url) separator = "&" if "?" in api_base else "?" completion_args["api_base"] = f"{api_base}{separator}GroupId={self.group_id}" ``` This matches MiniMax's official API format (as documented by LlamaFactory): ```bash curl --location 'https://api.minimaxi.chat/v1/text/chatcompletion?GroupId=你的GroupId' \ --header 'Authorization: Bearer 你的API_Key' ``` ## Test plan - [ ] Verify MiniMax API calls work with GroupId query parameter - [ ] Verify backward compatibility for other providers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 --- rag/llm/chat_model.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rag/llm/chat_model.py b/rag/llm/chat_model.py index b8a4a5a0de..717c43ad93 100644 --- a/rag/llm/chat_model.py +++ b/rag/llm/chat_model.py @@ -1298,6 +1298,17 @@ class LiteLLMBase(ABC): elif self.provider == SupportedLiteLLMProvider.Azure_OpenAI: self.api_key = json.loads(key).get("api_key", "") self.api_version = json.loads(key).get("api_version", "2024-02-01") + elif self.provider == SupportedLiteLLMProvider.MiniMax: + # MiniMax requires GroupId as a query parameter for API authentication + try: + key_obj = json.loads(key) if isinstance(key, str) else key + self.api_key = key_obj.get("api_key", key) if isinstance(key_obj, dict) else key + self.group_id = key_obj.get("group_id", "") if isinstance(key_obj, dict) else "" + except (json.JSONDecodeError, TypeError): + self.api_key = key + self.group_id = "" + else: + self.group_id = "" def _get_delay(self): return self.base_delay * random.uniform(10, 150) @@ -1848,6 +1859,11 @@ class LiteLLMBase(ABC): extra_headers = deepcopy(completion_args.get("extra_headers") or {}) if self.provider == SupportedLiteLLMProvider.Ollama and self.api_key and "Authorization" not in extra_headers: extra_headers["Authorization"] = f"Bearer {self.api_key}" + # MiniMax requires GroupId as a query parameter for API authentication + if self.provider == SupportedLiteLLMProvider.MiniMax and hasattr(self, 'group_id') and self.group_id: + api_base = completion_args.get("api_base", self.base_url) + separator = "&" if "?" in api_base else "?" + completion_args["api_base"] = f"{api_base}{separator}GroupId={self.group_id}" if extra_headers: completion_args["extra_headers"] = extra_headers return completion_args