feat: integrate MiniMax into model router, backend config, and common
common.py: - Add minimax_chat → MiniMax/MiniMax-Text-01 to _BACKEND_DEFAULT_MODELS - Add minimax/minimax_chat aliases to _BACKEND_ALIASES backend_config.py: - Add minimax_chat to set_optimizer_backend() valid set - Add minimax_chat to set_target_backend() valid set - Add minimax_chat to is_optimizer_chat_backend() - Add minimax_chat to is_target_chat_backend() __init__.py: - Import minimax_backend as _minimax - Add minimax_chat to set_backend() legacy handler - Add minimax_chat to get_backend_name() reporting - Route chat_target() and chat_target_messages() to _minimax - Update NotImplementedError messages to list minimax_chat - Aggregate _minimax into get_token_summary() - Add _minimax.reset_token_tracker() - Add configure_minimax_chat() delegator - Add _minimax to set_reasoning_effort() and set_target_deployment()
This commit is contained in:
@@ -6,6 +6,7 @@ from typing import Any
|
|||||||
|
|
||||||
from skillopt.model import azure_openai as _openai
|
from skillopt.model import azure_openai as _openai
|
||||||
from skillopt.model import claude_backend as _claude
|
from skillopt.model import claude_backend as _claude
|
||||||
|
from skillopt.model import minimax_backend as _minimax
|
||||||
from skillopt.model import qwen_backend as _qwen
|
from skillopt.model import qwen_backend as _qwen
|
||||||
from skillopt.model.backend_config import ( # noqa: F401
|
from skillopt.model.backend_config import ( # noqa: F401
|
||||||
configure_claude_code_exec,
|
configure_claude_code_exec,
|
||||||
@@ -50,6 +51,10 @@ def set_backend(name: str | None) -> str:
|
|||||||
set_optimizer_backend("openai_chat")
|
set_optimizer_backend("openai_chat")
|
||||||
set_target_backend("qwen_chat")
|
set_target_backend("qwen_chat")
|
||||||
return "qwen_chat"
|
return "qwen_chat"
|
||||||
|
if normalized in {"minimax", "minimax_chat"}:
|
||||||
|
set_optimizer_backend("openai_chat")
|
||||||
|
set_target_backend("minimax_chat")
|
||||||
|
return "minimax_chat"
|
||||||
raise ValueError(f"Unsupported legacy backend: {name!r}")
|
raise ValueError(f"Unsupported legacy backend: {name!r}")
|
||||||
|
|
||||||
|
|
||||||
@@ -65,6 +70,8 @@ def get_backend_name() -> str:
|
|||||||
return "codex"
|
return "codex"
|
||||||
if optimizer == "openai_chat" and target == "qwen_chat":
|
if optimizer == "openai_chat" and target == "qwen_chat":
|
||||||
return "qwen_chat"
|
return "qwen_chat"
|
||||||
|
if optimizer == "openai_chat" and target == "minimax_chat":
|
||||||
|
return "minimax_chat"
|
||||||
return f"{optimizer}+{target}"
|
return f"{optimizer}+{target}"
|
||||||
|
|
||||||
|
|
||||||
@@ -124,9 +131,18 @@ def chat_target(
|
|||||||
stage=stage,
|
stage=stage,
|
||||||
reasoning_effort=reasoning_effort,
|
reasoning_effort=reasoning_effort,
|
||||||
)
|
)
|
||||||
|
if get_target_backend() == "minimax_chat":
|
||||||
|
return _minimax.chat_target(
|
||||||
|
system=system,
|
||||||
|
user=user,
|
||||||
|
max_completion_tokens=max_completion_tokens,
|
||||||
|
retries=retries,
|
||||||
|
stage=stage,
|
||||||
|
reasoning_effort=reasoning_effort,
|
||||||
|
)
|
||||||
if not is_target_chat_backend():
|
if not is_target_chat_backend():
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"chat_target is only supported with target_backend=openai_chat, claude_chat, or qwen_chat. "
|
"chat_target is only supported with target_backend=openai_chat, claude_chat, qwen_chat, or minimax_chat. "
|
||||||
"Exec backends are handled in environment-specific rollout code."
|
"Exec backends are handled in environment-specific rollout code."
|
||||||
)
|
)
|
||||||
return _openai.chat_target(
|
return _openai.chat_target(
|
||||||
@@ -210,9 +226,20 @@ def chat_target_messages(
|
|||||||
tool_choice=tool_choice,
|
tool_choice=tool_choice,
|
||||||
return_message=return_message,
|
return_message=return_message,
|
||||||
)
|
)
|
||||||
|
if get_target_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,
|
||||||
|
)
|
||||||
if not is_target_chat_backend():
|
if not is_target_chat_backend():
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"chat_target_messages is only supported with target_backend=openai_chat, claude_chat, or qwen_chat. "
|
"chat_target_messages is only supported with target_backend=openai_chat, claude_chat, qwen_chat, or minimax_chat. "
|
||||||
"Exec backends are handled in environment-specific rollout code."
|
"Exec backends are handled in environment-specific rollout code."
|
||||||
)
|
)
|
||||||
return _openai.chat_target_messages(
|
return _openai.chat_target_messages(
|
||||||
@@ -301,6 +328,17 @@ def get_token_summary() -> dict:
|
|||||||
summary[stage]["prompt_tokens"] += values["prompt_tokens"]
|
summary[stage]["prompt_tokens"] += values["prompt_tokens"]
|
||||||
summary[stage]["completion_tokens"] += values["completion_tokens"]
|
summary[stage]["completion_tokens"] += values["completion_tokens"]
|
||||||
summary[stage]["total_tokens"] += values["total_tokens"]
|
summary[stage]["total_tokens"] += values["total_tokens"]
|
||||||
|
minimax_summary = _minimax.get_token_summary()
|
||||||
|
for stage, values in minimax_summary.items():
|
||||||
|
if stage == "_total":
|
||||||
|
continue
|
||||||
|
if stage not in summary:
|
||||||
|
summary[stage] = values
|
||||||
|
continue
|
||||||
|
summary[stage]["calls"] += values["calls"]
|
||||||
|
summary[stage]["prompt_tokens"] += values["prompt_tokens"]
|
||||||
|
summary[stage]["completion_tokens"] += values["completion_tokens"]
|
||||||
|
summary[stage]["total_tokens"] += values["total_tokens"]
|
||||||
total = {
|
total = {
|
||||||
"calls": 0,
|
"calls": 0,
|
||||||
"prompt_tokens": 0,
|
"prompt_tokens": 0,
|
||||||
@@ -322,6 +360,7 @@ def reset_token_tracker() -> None:
|
|||||||
_openai.reset_token_tracker()
|
_openai.reset_token_tracker()
|
||||||
_claude.reset_token_tracker()
|
_claude.reset_token_tracker()
|
||||||
_qwen.reset_token_tracker()
|
_qwen.reset_token_tracker()
|
||||||
|
_minimax.reset_token_tracker()
|
||||||
|
|
||||||
|
|
||||||
def configure_azure_openai(
|
def configure_azure_openai(
|
||||||
@@ -386,16 +425,37 @@ def configure_qwen_chat(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def configure_minimax_chat(
|
||||||
|
*,
|
||||||
|
base_url: str | None = None,
|
||||||
|
api_key: str | None = None,
|
||||||
|
temperature: float | str | None = None,
|
||||||
|
timeout_seconds: float | str | None = None,
|
||||||
|
max_tokens: int | str | None = None,
|
||||||
|
enable_thinking: bool | str | None = None,
|
||||||
|
) -> None:
|
||||||
|
_minimax.configure_minimax_chat(
|
||||||
|
base_url=base_url,
|
||||||
|
api_key=api_key,
|
||||||
|
temperature=temperature,
|
||||||
|
timeout_seconds=timeout_seconds,
|
||||||
|
max_tokens=max_tokens,
|
||||||
|
enable_thinking=enable_thinking,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def set_reasoning_effort(effort: str | None) -> None:
|
def set_reasoning_effort(effort: str | None) -> None:
|
||||||
_openai.set_reasoning_effort(effort)
|
_openai.set_reasoning_effort(effort)
|
||||||
_claude.set_reasoning_effort(effort)
|
_claude.set_reasoning_effort(effort)
|
||||||
_qwen.set_reasoning_effort(effort)
|
_qwen.set_reasoning_effort(effort)
|
||||||
|
_minimax.set_reasoning_effort(effort)
|
||||||
|
|
||||||
|
|
||||||
def set_target_deployment(deployment: str) -> None:
|
def set_target_deployment(deployment: str) -> None:
|
||||||
_openai.set_target_deployment(deployment)
|
_openai.set_target_deployment(deployment)
|
||||||
_claude.set_target_deployment(deployment)
|
_claude.set_target_deployment(deployment)
|
||||||
_qwen.set_target_deployment(deployment)
|
_qwen.set_target_deployment(deployment)
|
||||||
|
_minimax.set_target_deployment(deployment)
|
||||||
|
|
||||||
|
|
||||||
def set_optimizer_deployment(deployment: str) -> None:
|
def set_optimizer_deployment(deployment: str) -> None:
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS = max(
|
|||||||
def set_optimizer_backend(backend: str) -> None:
|
def set_optimizer_backend(backend: str) -> None:
|
||||||
global OPTIMIZER_BACKEND
|
global OPTIMIZER_BACKEND
|
||||||
OPTIMIZER_BACKEND = normalize_backend_name(backend or "openai_chat")
|
OPTIMIZER_BACKEND = normalize_backend_name(backend or "openai_chat")
|
||||||
if OPTIMIZER_BACKEND not in {"openai_chat", "claude_chat"}:
|
if OPTIMIZER_BACKEND not in {"openai_chat", "claude_chat", "minimax_chat"}:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Unsupported optimizer backend: {OPTIMIZER_BACKEND!r}. "
|
f"Unsupported optimizer backend: {OPTIMIZER_BACKEND!r}. "
|
||||||
"Supported values are 'openai_chat' and 'claude_chat'."
|
"Supported values are 'openai_chat', 'claude_chat', and 'minimax_chat'."
|
||||||
)
|
)
|
||||||
os.environ["OPTIMIZER_BACKEND"] = OPTIMIZER_BACKEND
|
os.environ["OPTIMIZER_BACKEND"] = OPTIMIZER_BACKEND
|
||||||
|
|
||||||
@@ -64,10 +64,10 @@ def get_optimizer_backend() -> str:
|
|||||||
def set_target_backend(backend: str) -> None:
|
def set_target_backend(backend: str) -> None:
|
||||||
global TARGET_BACKEND
|
global TARGET_BACKEND
|
||||||
TARGET_BACKEND = normalize_backend_name(backend or "openai_chat")
|
TARGET_BACKEND = normalize_backend_name(backend or "openai_chat")
|
||||||
if TARGET_BACKEND not in {"openai_chat", "claude_chat", "qwen_chat", "codex_exec", "claude_code_exec"}:
|
if TARGET_BACKEND not in {"openai_chat", "claude_chat", "qwen_chat", "minimax_chat", "codex_exec", "claude_code_exec"}:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Unsupported target backend: {TARGET_BACKEND!r}. "
|
f"Unsupported target backend: {TARGET_BACKEND!r}. "
|
||||||
"Supported values are 'openai_chat', 'claude_chat', 'qwen_chat', 'codex_exec', and 'claude_code_exec'."
|
"Supported values are 'openai_chat', 'claude_chat', 'qwen_chat', 'minimax_chat', 'codex_exec', and 'claude_code_exec'."
|
||||||
)
|
)
|
||||||
os.environ["TARGET_BACKEND"] = TARGET_BACKEND
|
os.environ["TARGET_BACKEND"] = TARGET_BACKEND
|
||||||
|
|
||||||
@@ -81,11 +81,11 @@ def is_target_exec_backend() -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def is_optimizer_chat_backend() -> bool:
|
def is_optimizer_chat_backend() -> bool:
|
||||||
return OPTIMIZER_BACKEND in {"openai_chat", "claude_chat"}
|
return OPTIMIZER_BACKEND in {"openai_chat", "claude_chat", "minimax_chat"}
|
||||||
|
|
||||||
|
|
||||||
def is_target_chat_backend() -> bool:
|
def is_target_chat_backend() -> bool:
|
||||||
return TARGET_BACKEND in {"openai_chat", "claude_chat", "qwen_chat"}
|
return TARGET_BACKEND in {"openai_chat", "claude_chat", "qwen_chat", "minimax_chat"}
|
||||||
|
|
||||||
|
|
||||||
def configure_codex_exec(
|
def configure_codex_exec(
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ _BACKEND_DEFAULT_MODELS = {
|
|||||||
"claude_chat": "claude-sonnet-4-6",
|
"claude_chat": "claude-sonnet-4-6",
|
||||||
"claude_code_exec": "claude-sonnet-4-6",
|
"claude_code_exec": "claude-sonnet-4-6",
|
||||||
"qwen_chat": "Qwen/Qwen3.5-4B",
|
"qwen_chat": "Qwen/Qwen3.5-4B",
|
||||||
|
"minimax_chat": "MiniMax/MiniMax-Text-01",
|
||||||
}
|
}
|
||||||
|
|
||||||
_BACKEND_ALIASES = {
|
_BACKEND_ALIASES = {
|
||||||
@@ -41,6 +42,8 @@ _BACKEND_ALIASES = {
|
|||||||
"anthropic": "claude_chat",
|
"anthropic": "claude_chat",
|
||||||
"qwen": "qwen_chat",
|
"qwen": "qwen_chat",
|
||||||
"qwen_chat": "qwen_chat",
|
"qwen_chat": "qwen_chat",
|
||||||
|
"minimax": "minimax_chat",
|
||||||
|
"minimax_chat": "minimax_chat",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user