From 64a0a567761f616e5e02129b276aad1a055629f1 Mon Sep 17 00:00:00 2001 From: renearaos Date: Thu, 18 Jun 2026 20:30:44 -0400 Subject: [PATCH] fix(minimax): properly handle M2.x streaming reasoning - M2.x streaming chunks don't have 'reasoning' field like M3 - Detect delimiter to split reasoning from content - Emit reasoning chunks as reasoning_content immediately - Emit answer chunks as content after detected - Both M3 and M2.x verified working via opencode run --- litellm/llms/minimax/chat/transformation.py | 42 +++++++++++++-------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/litellm/llms/minimax/chat/transformation.py b/litellm/llms/minimax/chat/transformation.py index 92987b794c5..0a20495d63a 100644 --- a/litellm/llms/minimax/chat/transformation.py +++ b/litellm/llms/minimax/chat/transformation.py @@ -137,29 +137,39 @@ class MinimaxChatResponseIterator(OpenAIChatCompletionStreamingHandler): content = delta.get("content", "") if content and isinstance(content, str): - reasoning_matches = re.findall( - r"(.*?)", content, re.DOTALL - ) - if reasoning_matches: - self.pending_reasoning += "".join(reasoning_matches) + if "" in content and "" in content: + reasonings = re.findall( + r"(.*?)", content, re.DOTALL + ) + if reasonings: + self.pending_reasoning += "".join(reasonings) clean_content = re.sub( r".*?", "", content, flags=re.DOTALL ) - delta["content"] = clean_content if clean_content else None + delta["content"] = clean_content if clean_content.strip() else None if self.pending_reasoning: delta["reasoning_content"] = self.pending_reasoning self.started_reasoning_content = True - elif self.started_reasoning_content and not self.finished_reasoning_content: + elif "" in content and "" not in content: + clean_content = content.replace("", "", 1) + delta["content"] = None + delta["reasoning_content"] = clean_content.strip() + self.started_reasoning_content = True + elif "" in content and "" not in content: + parts = content.split("", 1) + before = parts[0].strip() + after = parts[1] if len(parts) > 1 else "" + if before: + delta["reasoning_content"] = before + delta["content"] = after if after.strip() else ("" if not after else None) self.finished_reasoning_content = True - self.pending_reasoning = "" - clean_content = re.sub( - r"", "", content - ) - delta["content"] = clean_content if clean_content else None - elif not self.started_reasoning_content: - if "" in content: - clean_content = content.replace("", "").replace("", "") - delta["content"] = clean_content if clean_content else None + elif has_reasoning: + pass + elif not self.finished_reasoning_content and content.strip(): + if not self.started_reasoning_content: + self.started_reasoning_content = True + delta["reasoning_content"] = content.strip() + delta["content"] = None return super().chunk_parser(chunk) except Exception: