From fa324b5ef189417a681deee0f42a0797176d04d8 Mon Sep 17 00:00:00 2001 From: "Mavis (MiniMax)" Date: Thu, 9 Jul 2026 15:41:30 -0400 Subject: [PATCH] fix(model): route chat_optimizer through minimax_chat (not just chat_target) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two missing pieces in the minimax_chat dispatch chain: 1. minimax_backend.py did not define chat_optimizer or chat_optimizer_messages; only chat_target / chat_target_messages existed. Any caller using optimizer_backend='minimax_chat' would hit AttributeError or fall through to _openai (Azure). 2. skillopt/model/__init__.py's chat_optimizer and chat_optimizer_messages dispatchers checked claude_chat and qwen_chat but not minimax_chat, so minimax_chat callers would silently fall through to _openai.chat_optimizer (the Azure path), which fails with 'Azure OpenAI endpoint is not configured' on any setup without AZURE_OPENAI_* env vars. Adds chat_optimizer to minimax_backend.py (mirrors chat_target via _chat_messages_impl) and minimax_chat branches to both chat_optimizer / chat_optimizer_messages dispatchers. Verified locally: 1-epoch training on a 4-item SearchQA-format dataset went from '[skip] no usable patches — skill unchanged' (baseline fallback) to a successful accept_new_best with success_patches=1 per step. Co-authored-by: jc --- skillopt/model/__init__.py | 22 ++++++++++++++++++++++ skillopt/model/minimax_backend.py | 28 +++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/skillopt/model/__init__.py b/skillopt/model/__init__.py index a09e6e0c..c38f3180 100644 --- a/skillopt/model/__init__.py +++ b/skillopt/model/__init__.py @@ -105,6 +105,16 @@ def chat_optimizer( reasoning_effort=reasoning_effort, timeout=timeout, ) + if get_optimizer_backend() == "minimax_chat": + return _minimax.chat_optimizer( + system=system, + user=user, + max_completion_tokens=max_completion_tokens, + retries=retries, + stage=stage, + reasoning_effort=reasoning_effort, + timeout=timeout, + ) return _openai.chat_optimizer( system=system, user=user, @@ -204,6 +214,18 @@ def chat_optimizer_messages( return_message=return_message, timeout=timeout, ) + if get_optimizer_backend() == "minimax_chat": + return _minimax.chat_target_messages( + messages=messages, + max_completion_tokens=max_completion_tokens, + retries=retries, + stage=stage, + reasoning_effort=reasoning_effort, + tools=tools, + tool_choice=tool_choice, + return_message=return_message, + timeout=timeout, + ) return _openai.chat_optimizer_messages( messages=messages, max_completion_tokens=max_completion_tokens, diff --git a/skillopt/model/minimax_backend.py b/skillopt/model/minimax_backend.py index 8c6add9c..7d9a42cb 100644 --- a/skillopt/model/minimax_backend.py +++ b/skillopt/model/minimax_backend.py @@ -222,7 +222,7 @@ def chat_target( stage: str = "target", reasoning_effort: str | None = None, timeout: float | None = None, -) -> tuple[str, dict[str, int]]: +) -> tuple[str, dict[int]]: del reasoning_effort messages = [{"role": "system", "content": system}, {"role": "user", "content": user}] return _chat_messages_impl( @@ -234,6 +234,32 @@ def chat_target( ) +def chat_optimizer( + system: str, + user: str, + max_completion_tokens: int = 16384, + retries: int = 5, + stage: str = "optimizer", + reasoning_effort: str | None = None, + timeout: float | None = None, +) -> tuple[str, dict[int]]: + """Optimizer chat call. Backend stores the trained skill; uses the same + MiniMax-proxied OpenAI-compat endpoint as `chat_target`. Added in the + parallel-training fix; previously missing in skillopt 0.2.0's + miniamax backend, which forced the dispatcher into _openai.chat_optimizer + (Azure) and produced "[skip] no usable patches" for any user running + optimizer+target on `minimax_chat`. + """ + messages = [{"role": "system", "content": system}, {"role": "user", "content": user}] + return _chat_messages_impl( + messages, + max_completion_tokens, + retries, + stage, + timeout=timeout, + ) + + def chat_target_messages( messages: list[dict[str, Any]], max_completion_tokens: int = 16384,